• XSS.stack #1 – первый литературный журнал от юзеров форума

Ограничения rundll32

dark-slesh

floppy-диск
Пользователь
Регистрация
02.05.2011
Сообщения
6
Реакции
0
В общем вкратце информация.
1) Есть DLL которая ставит хук (сплайсинг) на CreateProcessA/W для процесса в котором запущена
2) Если требуется то запускает определенный процесс через ShellExecute
3) В хуке правится флаг запуска на SUSPENDED
4) Записывается шелкод который подгрузит эту же DLL в запускаемый процесс (через LdrLoadDll).
5) Далее QueueUserApc на адрес шелкода.
6) ResumeThread

В итоге всегда наша DLL будет стартовать перед кодом запускаемой программы.
Всё работает идеально и ровно.... но до тех пор пока DLL не стартует в rundll32

В данном случае при запуске нужного процесса из DLL, попадаю на хук, далее всё выполняется как надо, но запускаемый процесс падает, причем падение происходит в недрах ntdll. LdrLoadDll -> RtlDosApplyFileIsolationRedirection -> еще штук 5 вложенных вызовов. т.е. DLL еще даже не пытается грузить, просто проверяются пути (что-то связанное с технологией winsxs)

т.е. получается что rundll32 что-то правит у себя, и это наследуется в дочернем процессе и собственно говоря не дает нормально работать коду

P.S.
1) QueueUserApc потому что обязательное требование чтобы код DLL выполнился до старта кода программы
2) LdrLoadDll - используется из-за определенное специфики, которая не имеет отношение к вопросу
3) ShellExecute потому что приходится запускать некоторые программы заранее не зная расположение их, а также запускать не только программы но и открывать файлы.
4) Тестил на Win Vista x32 SP2 / Win Vista x64 SP2 / Win Vista x64 SP1 / Win 7 x32 / Win 7 x64 / Win 7 x64 SP 1 - везде один и тот же результат.

В общем главный вопрос - что мог такого сделать rundll чтобы появлялась такая ошибка. Или как можно избежать этого?

P.P.S
В общем IDA + HexRay показали что такой баг не возникает, если прибить в rundll вызов ActivateActCtx. Теперь интересно, чтоже там могло такого произойти серьездного
 
И такс, кому хочется покопаться, накидал тестилку. Смысл тестилки таков:
1) Тестовая DLL загружается или через тестовую прогу или через rundll32 и выполняется TestProc
2) В TestProc запускается через CreateProcessA процесс child.exe с флагом CREATE_SUSPENDED
3) Далее в АП запущенного процесса закидывается шелкод
4) Ставится APC на шелкод
5) Запускается главный поток программы.

В аттаче все тестовые проги/dll и их исходники.


И так, запускаю первый тест (тестовая программя делает LoadLibrary("test.dll") + GetProcAddress("TestProc") и выполняет TestProc).
DebugView показывает [PID][FROM:PID] Message

[2012] [TEST:2012] Started  // запустился тестовый процесс
[2012] [DLL:2012] Attach  // загрузилась тестовая DLL
[2012] [DLL:2012] TestProc Started  // Начала выполнятся TestProc
[2012] [DLL:2012] DllName = C:\TempData\TestBug\test.dll  // определили путь к DLL
[2012] [DLL:2012] LdrLoadDllAddr = 771FC43A  // Нашли адрес LdrLoadDll
[2012] [DLL:2012] VirtualAllocEx = 001C0000  // Где выделили память в запущенном процессе
[2012] [TEST:2012] Finished // Завершили работу
[2012] [DLL:2012] Detach  // система выгрузила DLL
[2644] [DLL:2644] Attach  // DLL загрузилась в дочерний процесс (видно что до старта точки входа)
[2644] [CHILD:2644]Started  // Дочерний процесс загрузился

Далее загружаем DLL через rundll32.exe test.dll,TestProc
[2640] [DLL:2640] Attach
[2640] [DLL:2640] TestProc Started
[2640] [DLL:2640] DllName = C:\TempData\TestBug\test.dll
[2640] [DLL:2640] LdrLoadDllAddr = 771FC43A
[2640] [DLL:2640] VirtualAllocEx = 001C0000
[2640] [DLL:2640] Detach

И ловим падение дочернего процесса еще до загрузки DLL. на разный ОС стек вызовов чуть отличается.

Win 7 X64 SP1 (видно что образ DLL уже погружен)
  ntdll.dll!_NtRaiseException@12()  + 0x12 байт
  ntdll.dll!_NtRaiseException@12()  + 0x12 байт
  ntdll.dll!_LdrpProcessStaticImports@8()  + 0x83 байт
  ntdll.dll!_LdrpLoadDll@24()  + 0x14c1 байт
  ntdll.dll!_LdrLoadDll@16()  + 0x7b байт
  001c0016() // Как раз и есть шелкод
  ntdll.dll!_RtlDispatchAPC@12()  + 0x42 байт


Win Vista X32 SP2 (видно что образ DLL не погружен)
  ntdll.dll!_RtlpFindNextActivationContextSection@16()  - 0xbfc6 байт
  ntdll.dll!_RtlpFindFirstActivationContextSection@16()  + 0x41 байт
  ntdll.dll!_RtlFindActivationContextSectionString@20()  + 0x79 байт
  ntdll.dll!_WinSqmAddToStream@16()  + 0x29d05 байт
  ntdll.dll!_RtlDosApplyFileIsolationRedirection_Ustr@36()  + 0x204 байт
  ntdll.dll!_LdrLoadDll@16()  + 0xb1 байт
  00140016()  // Как раз и есть шелкод
  kernel32.dll!_BaseDispatchAPC@12()  + 0x46 байт

Win 7 X32 (видно что образ DLL не погружен)
  ntdll.dll!_RtlpFindNextActivationContextSection@16()  - 0x2d860 байт
  ntdll.dll!_RtlpFindFirstActivationContextSection@16()  + 0x41 байт
  ntdll.dll!_RtlFindActivationContextSectionString@20()  + 0x79 байт
  ntdll.dll!_AitFireParentUsageEvent@16()  - 0x49090 байт
  ntdll.dll!_RtlDosApplyFileIsolationRedirection_Ustr@36()  + 0x200 байт
  ntdll.dll!_LdrpApplyFileNameRedirection@28()  + 0x5c байт
  ntdll.dll!_LdrpLoadDll@24()  + 0xae байт
  ntdll.dll!_LdrLoadDll@16()  + 0x74 байт
  00150016()
  ntdll.dll!_RtlDispatchAPC@12()  + 0x42 байт

В общем-то, для x64 систем, ошибка там же происходит, только этого не видно из-за WOW64.
На XP SP3 бага нет.
 

Вложения

  • TestBug.zip
    5.9 КБ · Просмотры: 78
В общем тесты показали, что и на Win XP SP3 такой же баг всплывает тока в других процессах.
Вообще предполагаю что это нормальное поведение т.к. почти везде в системе вызовы LdrLoadDll обернуты в try except
 
глянул на w7 sp1 x64, действительно падает вот колл стек
Код:
(17e0.11c4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll_77380000!RtlDecodePointer+0x6c:
773b9dc1 8b7b10          mov     edi,dword ptr [ebx+10h] ds:002b:004e5164=????????
0:000:x86> k
ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
0018f4e0 773aeb12 ntdll_77380000!RtlDecodePointer+0x6c
0018f4f8 773aed19 ntdll_77380000!RtlUpcaseUnicodeChar+0x2d9
0018f54c 773af3df ntdll_77380000!RtlFindActivationContextSectionString+0x81
0018f608 773af1aa ntdll_77380000!RtlDosApplyFileIsolationRedirection_Ustr+0x435
0018f764 773afaf6 ntdll_77380000!RtlDosApplyFileIsolationRedirection_Ustr+0x200
0018f7a4 773bc2ac ntdll_77380000!RtlAnsiCharToUnicodeChar+0x1bc
0018f928 773bc4d5 ntdll_77380000!RtlRunOnceComplete+0x2a7
0018f974 773f6536 ntdll_77380000!LdrLoadDll+0x7b
0018f9cc 7739004d ntdll_77380000!Ordinal8+0x42
0018fd00 773b9e79 ntdll_77380000!KiUserApcDispatcher+0x25
0018fd10 00000000 ntdll_77380000!LdrInitializeThunk+0x10

дурацкие символы в windbg ( на самом деле RtlRunOnceComplete+0x2a7 == LdrpLoadDll, RtlAnsiCharToUnicodeChar+0x1bc == LdrpApplyFileNameRedirection и т.д. ) не дают нормально разобраться в чем дело, и w7х86 под рукой тоже нету

LdrLoadDll -> LdrpLoadDll -> LdrpApplyFileNameRedirection -> RtlDosApplyFileIsolationRedirection -> RtlDosApplyFileIsolationRedirection_Ustr и так дальше до sxs отлаживать сложно без символов да и в7х64 накладывает некоторые не удобства. расскажи как повторить баг на хп сп 3, там имхо будет намного проще с ним разобраться. если руки дойдут обязательно вернусь интересно что же там такое.
 
На win xp это проявлялось в следующем месте:
1) Инжектилась DLL в Explorer
2) Ставились хуки на CreateProcess
3) Win+R
4) Далее вводилось имя проги (calc / notepad / любое другое) в поле Открыть.
5) OK
И повторялось подобное. Кстати с Total Commander тоже самое.

В общем всё было завязано на том, что программа запускалась через ShellExecute и ей подобные, а в хуке CreateProcess подгружалась нужная dll.

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


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх