发表于 2018-7-28 00:12

申请会员ID:C0ss4ck【申请通过】

申请ID:C0ss4ck
个人邮箱:769233061@qq.com (刚才发了篇一摸一样的忘记给邮箱了【滑稽】)
原创技术文章:
# Windows Kernel
一只CTF二进制弱鸡打PWN打累了回头刷了点逆向……这道题是reversing.kr上面的唯一一道和Windows内核相关的题目,挑出来讲一讲咯,顺便用作我的申请文章。
### Analysis of WindowsKernel.exe
###### Winmain(0x00401000):
```
push      0                                        ;dwInitParam
push         offset DialogFunc      ;lpDialogFunc
push      0                                        ;hWndParent
push      65h                                        ;lpTemplateName
push      eax                                        ;hInstance
call      ds:DialogBoxParamW
```
###### DialogFunc(0x00401020):
```
BOOL __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4)
{
      if ( a2 == 272 )                                                      //Timer set
      {
                SetDlgItemTextW(hWnd, 1001, L"Wait.. ");
                SetTimer(hWnd, 0x464u, 0x3E8u, 0);
                return 1;
      }
      if ( a2 != 273 )
      {
                if ( a2 == 275 )                                                //Error ocurr
                {
                        KillTimer(hWnd, 0x464u);
                        HandleError(hWnd);
                        return 1;
                }
                return 0;
      }
      if ( (unsigned __int16)a3 == 2 )                        //Dialog end
      {
                SetDlgItemTextW(hWnd, 1001, L"Wait.. ");
                CloseProc();
                EndDialog(hWnd, 2);
                return 1;
      }
      if ( (unsigned __int16)a3 == 1002 )                        //Unknown
      {
                if ( a3 >> 16 == 1024 )
                {
                        Sleep(0x1F4u);
                        return 1;
                }
                return 1;
      }
      if ( (unsigned __int16)a3 != 1003 )
                return 0;
      check(hWnd);                                                                //Judge the input
      return 1;
}
```
###### check(0x00401110):
```
HWND __thiscall check(HWND hDlg)
{
      HWND v1; // edi
      HWND result; // eax
      HWND v3; // eax
      HWND v4; // eax
      HWND v5; // eax
      WCHAR String; //

      v1 = hDlg;
      GetDlgItemTextW(hDlg, 1003, &String, 512);
      if ( lstrcmpW(&String, L"Enable") )
      {
                result = (HWND)lstrcmpW(&String, L"Check");
                if ( !result )
                {
                        if ( click(v1, 0x2000u) == 1 )
                              MessageBoxW(v1, L"Correct!", L"Reversing.Kr", 0x40u);
                        else
                              MessageBoxW(v1, L"Wrong", L"Reversing.Kr", 0x10u);
                        SetDlgItemTextW(v1, 1002, &word_4021F0);
                        v5 = GetDlgItem(v1, 1002);
                        EnableWindow(v5, 0);
                        result = (HWND)SetDlgItemTextW(v1, 1003, L"Enable");
                }
      }
      else if ( click(v1, 0x1000u) )
      {
                v3 = GetDlgItem(v1, 1002);
                EnableWindow(v3, 1);
                SetDlgItemTextW(v1, 1003, L"Check");
                SetDlgItemTextW(v1, 1002, &word_4021F0);
                v4 = GetDlgItem(v1, 1002);
                result = SetFocus(v4);
      }
      else
      {
                result = (HWND)MessageBoxW(v1, L"Device Error", L"Reversing.Kr", 0x10u);
      }
      return result;
}
```

两次click,arg1==0x1000是点击Enable,按钮变成Check;arg1==0x2000是点击Check,回显Correct或者Wrong。

后来翻了夜影老哥的WP,发现这个0x1000和0x2000是dwIoControlCode,即DeviceIoControl的arg1,而dwIoControlCode值就是Windows内核中宏定义CTL_CODE所定义的。

详情请看(https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms902086(v=msdn.10))
###### click(0x00401280):
```
int __usercall sub_401280@<eax>(HWND a1@<edi>, DWORD dwIoControlCode)
{
      HANDLE v2; // esi
      int result; // eax
      DWORD BytesReturned; //
      int OutBuffer; //

      v2 = CreateFileW(L"\\\\.\\RevKr", 0xC0000000, 0, 0, 3u, 0, 0);
      if ( v2 == (HANDLE) - 1 )
      {
                MessageBoxW(a1, L" CreateFile", L"Reversing.Kr", 0x10u);
                result = 0;
      }
      else if ( DeviceIoControl(v2, dwIoControlCode, 0, 0, &OutBuffer, 4u, &BytesReturned, 0) )
      {
                CloseHandle(v2);
                result = OutBuffer;
      }
      else
      {
                MessageBoxW(a1, L" DeviceIoControl", L"Reversing.Kr", 0x10u);
                result = 0;
      }
      return result;
}
```
click函数内很明显通过DeviceIoControl与键盘设备进行了交互(快看这里有dwIoControlCode),并调用了WinKer.sys中的函数

接下来分析WinKer.sys

### Analysis of WinKer.sys
###### KeyBoardInput(0x00011266):
这里通过静态分析找到了接收键盘设备输入的函数
```
void __stdcall getInput(struct _KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
char input; // al

input = READ_PORT_UCHAR((PUCHAR)0x60);
sub_111DC(input);
}
```
READ_PORT_UCHAR是Windows内核I/O中从指定的PORT读入一字节数据的函数,其参数(PUCHAR)PORT在此为0x60,而大多数PC键盘控制器在PORT0x60与0x64是可寻址的,故此处为从键盘控制器逐次读入1byte。
###### Judge(0x000111DC,0x00011156,0x000110D0):
这些理解起来都简单。
在第一个Judge中通过switch(judgenum)先检查前3个byte的值,再检查最后1byte值,若正确则judgenum=100,并进入下一个Judge;
在第二个Judge中先对第5到最后的byte进行异或0x12的处理,再通过switch(judgenum)检查第5到7个byte,最后检查第8个byte,若正确则judgenum=200,并进入下一个Judge;
第三个Judge也是类似,只不过又对最后四字节进行了异或5的处理。

### Solve
解密脚本如下
```
s=
for i in range(4):
      s^=0x12
      s^=0x12
      s^=0x5
mid=''
for i in s:
      mid+=str(hex(i))
print mid
```
得到a59295b0a097b194a39898a5
对应(https://blog.csdn.net/cmdasm/article/details/10168907)解码得keybdinthook

Hmily 发表于 2018-8-1 11:06

I D:C0ss4ck
邮箱:769233061@qq.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

ps:登录后把文章整理一下发到脱壳破解CTF分类吧。

C0ss4ck 发表于 2018-8-2 23:58

来报到了{:1_893:}
页: [1]
查看完整版本: 申请会员ID:C0ss4ck【申请通过】