[Writeup] Vòng loại WhiteHat Grand Prix 2015: Rev450

sunny

VIP Members
30/06/2014
869
1.849 bài viết
[Writeup] Vòng loại WhiteHat Grand Prix 2015: Rev450
Nguồn: PiggyBird (https://github.com/duc-le/ctf-writeu...450/writeup.md)

Cảm ơn các bạn đã chia sẻ.

Reversing - 450
Flag = WhiteHat{sha1(upper(key))}
Overview

The target is an 64-bit exe file statically linked to the MFC library. It is an MFC dialog-based application that has theWhiteHat icon and an about menu appended to the dialog's system menu.
The dialog has just 2 controls: an edit control and a push button. We tried several test input and hit the button but no message shown up. The button click just makes the application exit. We also tried to set breakpoints atGetWindowTextW and GetDlgItemTextW to find out when the application get text from the edit control but we still had no chance.
The challenge here is to find the program logic with no clue of how the input text is processed. We may start by investigating the mainCRTStartup, then AfxWinMain, then the inherited CWinApp::InitInstance ... However, we will mention another approach in this writeup: the application GUI components are hints to discover the program structure.

The dialog event handlers

To understand the program, we have to find the dialog event handlers. For MFC dialog-based applications, there are 2 main entry-points:

  • The inherited CDialog::OnInitDialog.
  • The GetThisMessageMap static method that returns the AFX_MSGMAP structure (you can read source code ofBEGIN_MESSAGE_MAP, END_MESSAGE_MAP and DECLARE_MESSAGE_MAP macros for more information). Here's the AFX_MSGMAP structure definition:
[SUB]
14899399462015-11-03_13-52-39.png
[/SUB]





Finding the inherited CDialog::OnInitDialog

Our approach is based on the WhiteHat icon of this application. A dialog has no icon (more precisely, it has the default application icon) until we explicitly set new icon for it by sending WM_SETICON (0x0080) message. So we fire up WinDbg and set breakpoint at SendMessageW:
[SUB]
14899399462015-11-03_13-53-24.png
[/SUB]





The breakpoint is hit twice, first with ICON_BIG (0x1) parameter, then ICON_SMALL (0x0). Here's the call stack when the breakpoint is hit: [SUB]
14899399462015-11-03_13-53-37.png
[/SUB]




Trace back to offset 0x2048 and offset 0x2421 we can easily find out that the inherited CDialog::OnInitDialog is at0x2300.
We can use the same method with the about menu. This menu is appended to the dialog's system menu. To do so the dialog should call the GetSystemMenu function. By setting breakpoint at User32!GetSystemMenu we can also trace back to CDialog::OnInitDialog at 0x2300.
Actually all those setups are not neccessary to by placed at OnInitDialog, but they must be called after the dialog has been created (maybe in some event handlers). We would still use the same approach in that case.

Finding the message map

We try clicking the about menu ("About WhiteHatContest...") and an about dialog will show up. This means that the application should call one of the following functions:

  • DialogBoxParamW
  • DialogBoxIndrectParamW
  • CreateDialogParamW
  • CreateDialogIndrectParamW
We set breakpoints on all those function calls then try clicking the about menu again. Breakpoint is hit atCreateDialogIndirectParamW [SUB]
14899399462015-11-03_13-53-53.png
[/SUB]





0x2543 is the lowest address in the call stack. We might guess that other addresses are from the MFC static library. From 0x2543 we can easily navigate to 0x2480 where the WM_SYSCOMMAND's handler starts. From there we just "Jump to xref" to locate the message map structure of the dialog at 0x211290:
14899399462015-11-03_13-54-48.png





By doing a quick investigation on all those message handlers we figure out that they just do the "default" (MFC generated) tasks. The OK button handler just sends the message WM_NCDESTROY to the dialog, no input text check here. So we just need to focus on the inherited CDialog::OnInitDialog at 0x2300.

The main logic

Back to CDialog::OnInitDialog at 0x2300, there are just one small suspicous code snippet:
[SUB]
14899399462015-11-03_13-55-07.png
[/SUB]





The application initializes an instance of an unknown class that we named WTF. This class has method table at0x210DA8. From there we can find all methods and analyze the data structure of the class. Here's the pseudo code of the WTF class:
14899399462015-11-03_13-56-04.png

14899399462015-11-03_13-56-53.png

14899399462015-11-03_13-57-11.png

14899399462015-11-03_13-57-38.png

14899399462015-11-03_13-58-05.png





The logic is quite simple, key is an Unicode string of 42 characters. It is encrypted using xor, add (subtract) and notoperations. The encrypted buffer is then compared every 4 bytes with a pre-calculated buffer. This class also has a decrypt method to inverse the encrypt operation.

Key generation

Here are the key and flag generated by our Python script:
1489939946z1.png

A final note on flag submission: although the key is a MSVC Unicode string (16-bit each character), we should UTF-8 encode it before getting sha1 checksum or else we would receive "wrong flag" message from the scoreboard!
 
Chỉnh sửa lần cuối bởi người điều hành:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Bên trên