攻防世界——MyDriver2-397

IDA分析

NTSTATUS __stdcall DriverEntry(_DRIVER_OBJECT *DriverObject, PUNICODE_STRING RegistryPath)
{
  NTSTATUS result; // eax
  BOOLEAN IsWdmVersionAvailable; // al
  const WCHAR *v5; // rdx
  int v6; // ebx
  PVOID SystemRoutineAddress; // rax
  struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-38h] BYREF
  struct _UNICODE_STRING SymbolicLinkName; // [rsp+50h] [rbp-28h] BYREF
  struct _UNICODE_STRING SystemRoutineName; // [rsp+60h] [rbp-18h] BYREF
  PDEVICE_OBJECT DeviceObject; // [rsp+80h] [rbp+8h] BYREF

  DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)&sub_116A4;// Create
  DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)&sub_116A4;
  DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)&sub_116CC;
  DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_11660;
  RtlInitUnicodeString(&DestinationString, L"\\Device\\Myhook");
  result = IoCreateDevice(DriverObject, 0, &DestinationString, 0x22u, 0, 0, &DeviceObject);
  if ( result >= 0 )
  {
    IsWdmVersionAvailable = IoIsWdmVersionAvailable(1u, 0x10u);
    v5 = L"\\DosDevices\\Global\\Myhook";
    if ( !IsWdmVersionAvailable )
      v5 = L"\\DosDevices\\Myhook";
    RtlInitUnicodeString(&SymbolicLinkName, v5);
    v6 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
    if ( v6 >= 0 )
    {
      sub_11008();
      qword_16448 = (__int64)ExAllocatePool(NonPagedPool, 0x3200ui64);
      memmove((void *)qword_16448, &unk_13110, 0x3200ui64);
      sub_113C8();
      RtlInitUnicodeString(&SystemRoutineName, L"NtCreateFile");
      SystemRoutineAddress = MmGetSystemRoutineAddress(&SystemRoutineName);
      Src = (void *)sub_110B8(SystemRoutineAddress);
      return 0;
    }
    else
    {
      IoDeleteDevice(DeviceObject);
      return v6;
    }
  }
  return result;
}

在这里插入图片描述
首先前面几个是派发函数和卸载函数。
进入卸载函数。
在这里插入图片描述
首先获取NtCreateFile的地址。然后再地址上进行了一些写入,我们可以猜测这个驱动是HOOK了NtCreateFile,在这里进行HOOK恢复。

sub_11008()

在这里插入图片描述
Create了taskhost程序

sub_113C8()

在这里插入图片描述
对byte_16390地址进行一些操作具体干嘛不清楚,猜测可能进行加密或者解密处理。

sub_110B8()

在这里插入图片描述
可以看到v15v14写入FF…25FF,在程序中是FF25是jmp指令的硬编码。
在这里插入图片描述
这里在关闭写保护和开启写保护,并把NtCreateFile地址写入到Poolwithtag中
在这里插入图片描述

通过以上分析可知,构建了一个V9函数用于跳转至真正的NtCreateFile,然后对NtCreateFile进行hook,hook跳转至sub_114D0函数,然后返回NtCreateFile的地址

sub_114D0

在这里插入图片描述
因为NtCreateFile以及被HOOK了,所以从上面可以看出当执行7次NtCreateFile时会进入函数sub_115DC(); sub_112B4中。

sub_115DC()

在这里插入图片描述
主要用于恢复HOOK

sub_112B4

在这里插入图片描述
在打开的文件中写入byte_16390(不知道写入什么)

总结

现在整个程序条理清楚了,HOOK NtCreateFile,在调用NtCreateFile7次以后,会把(加)解密的数组写入到打开的File中。所以可以判断sub_113C8中进行的操作就是获取flag。

获取FLAG

byte_16390 = [  0x70, 0x74, 0x37, 0x65, 0x47, 0x66, 0x05, 0x61, 0x11, 0x20,
  0x0C, 0x73, 0x6D, 0x41, 0x3A, 0x73, 0x36, 0x6D, 0x16, 0x6C,
  0x09, 0x5F, 0x28, 0x6E, 0x0B, 0x69, 0x31, 0x65, 0x6D, 0x68,
  0x5C, 0x6F, 0x58, 0x5F, 0x6A, 0x72, 0x02, 0x00, 0x78, 0x00,
  0x74, 0x00, 0x50, 0x00, 0x5F, 0x00, 0x67, 0x00, 0x69, 0x00,
  0x76, 0x00, 0x65, 0x00, 0x4D, 0x00, 0x65, 0x00, 0x5F, 0x00,
  0x66, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x67, 0x00, 0x5F, 0x00,
  0x32, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2E, 0x00, 0x74, 0x00,
  0x78, 0x00, 0x74, 0x00, 0x50, 0x00, 0x5F, 0x00, 0x67, 0x00,
  0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x4D, 0x00, 0x65, 0x00,
  0x5F, 0x00, 0x66, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x67, 0x00,
  0x5F, 0x00, 0x32, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2E, 0x00,
  0x74, 0x00, 0x78, 0x00, 0x74, 0x00, 0x50, 0x00]

byte_16310 = [
0x95, 0x13, 0x6E, 0x5C, 0xA2, 0x13, 0x58, 0x5C, 0xB3, 0x13,
0x54, 0x5C, 0x88, 0x13, 0x54, 0x5C, 0x9A, 0x13, 0x57, 0x5C,
0xA9, 0x13, 0x50, 0x5C, 0xA2, 0x13, 0x6E, 0x5C, 0xF7, 0x13,
0x02, 0x5C, 0xF6, 0x13, 0x1F, 0x5C, 0xB1, 0x13, 0x49, 0x5C,
0xB1, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

v1 = 0x54321CCC & 0xF0F0F0F0F0F0F0F0 ^ 0xCCC12345 & 0xF0F0F0F0F0F0F0F
v2 = v1 - 0x5C31139B
# print(v2)

for i in range(32):
    byte_16310[4*i] ^= (v1 & 0x000000ff)
    byte_16310[4*i+1] ^= ((v1 & 0x0000ff00)>>8)
    byte_16310[4*i + 2] ^= ((v1 & 0x00ff0000)>>16)
    byte_16310[4*i + 3] ^= ((v1 & 0xff000000)>>24)


byte_16310[v2] = 0
byte_16310[v2 + 1] = 0

v4 = 0
for i in range(128):
    byte_16390[i] ^= byte_16310[v4]
    v4 = (v4 + 1) % v2
k = 0
for i in byte_16390:
    if (i == 0):
        break
    else:
        k= k + 1

for i in range(k):
    print(chr(byte_16390[i] & 0xff),end = '')

flag为
RCTF{A_simple_Inline_hook_Drv}

void sendDriverCtrl( int & sendSocket, const double & simTime, const unsigned int & simFrame ) { Framework::RDBHandler myHandler; myHandler.initMsg(); RDB_DRIVER_CTRL_t *myDriver = ( RDB_DRIVER_CTRL_t* ) myHandler.addPackage( simTime, simFrame, RDB_PKG_ID_DRIVER_CTRL ); if ( !myDriver ) return; // do we have a valid nearest object? bool haveSensorObject = ( mNearestObject.base.id > 0 ); // sensor object must not be older than 1.0s double ownSpeed = sqrt( mOwnObject.ext.speed.x * mOwnObject.ext.speed.x + mOwnObject.ext.speed.y * mOwnObject.ext.speed.y ); double accelTgtDist = 0.0; double accelTgtSpeed = ( 30.0 - ownSpeed ) / 5.0; // default speed should be own preferred speed if ( haveSensorObject ) { // let's go for the same speed as preceding vehicle: if ( mNearestObject.ext.speed.x < -1.0e-3 ) accelTgtSpeed = 2.0 * mNearestObject.ext.speed.x / 5.0; else accelTgtSpeed = 0.0; // let's go for a 2s distance double tgtDist = ownSpeed * 2.0; if ( tgtDist < 10.0 ) // minimum distance to keep tgtDist = 10.0; accelTgtDist = ( mNearestObject.base.pos.x - tgtDist ) / 10.0; } fprintf( stderr, "sendDriverCtrl: accelDist = %.5lf, accelSpeed = %.5lf\n", accelTgtDist, accelTgtSpeed ); myDriver->playerId = 1; myDriver->accelTgt = accelTgtDist + accelTgtSpeed; myDriver->validityFlags = RDB_DRIVER_INPUT_VALIDITY_TGT_ACCEL | RDB_DRIVER_INPUT_VALIDITY_ADD_ON; int retVal = send( sendSocket, ( const char* ) ( myHandler.getMsg() ), myHandler.getMsgTotalSize(), 0 ); if ( !retVal ) fprintf( stderr, "sendDriverCtrl: could not send driver control\n" ); else fprintf( stderr, "sentDriverCtrl\n" ); }
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值