Skip to content

Several handle leaks in KohClient.c #3

@JohnLaTwC

Description

@JohnLaTwC

Issue 1: serverPipe not closed in error paths

warning: if you add a close at cleanup, it may be already closed in the function body and unless you set the handle value to -1 this will result in a wild close when the handle value is closed again at cleanup.

        serverPipe = KERNEL32$CreateNamedPipeA(impersonationPipe, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 1, 2048, 2048, 0, &SA);

        if (serverPipe == INVALID_HANDLE_VALUE) {
            BeaconPrintf(CALLBACK_ERROR, "[!] Creating named pipe %s using KERNEL32$CreateNamedPipeA failed with: %d\n", impersonationPipe, KERNEL32$GetLastError());
            goto cleanup;
        }
@@ at this point serverPipe is a valid handle@@ 

        if (!KERNEL32$ConnectNamedPipe(serverPipe, NULL)) {
            BeaconPrintf(CALLBACK_ERROR, "[!] KERNEL32$ConnectNamedPipe failed: %d\n", KERNEL32$GetLastError());
!            goto cleanup;   <<< fails to call KERNEL32$CloseHandle on serverPipe
        }

        // read 1 byte to satisfy the requirement that data is read from the pipe before it's used for impersonation
        fSuccess = KERNEL32$ReadFile(serverPipe, &message, 1, &bytesRead, NULL);
        if (!fSuccess) {
            BeaconPrintf(CALLBACK_ERROR, "[!] KERNEL32$ReadFile failed: %d\n", KERNEL32$GetLastError());
!            goto cleanup;   <<< fails to call KERNEL32$CloseHandle on serverPipe
        }

Issue 2: tokens not closed in error paths

The tokens are opened get closed in the main body but there are a couple of goto cleanup statements that will result in them not getting released.

            if (!ADVAPI32$OpenThreadToken(KERNEL32$GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &threadToken)) {
                BeaconPrintf(CALLBACK_ERROR, "[!] ADVAPI32$OpenThreadToken failed with: %d\n", KERNEL32$GetLastError());
                ADVAPI32$RevertToSelf();
                goto cleanup;
            }

            if (!ADVAPI32$DuplicateTokenEx(threadToken, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenPrimary, &duplicatedToken)) {
                BeaconPrintf(CALLBACK_ERROR, "[!] ADVAPI32$DuplicateTokenEx failed with: %d\n", KERNEL32$GetLastError());
                ADVAPI32$RevertToSelf();
!                goto cleanup;  <<< leaks handle to threadToken
            }

            BeaconPrintf(CALLBACK_OUTPUT, "[*] Impersonated token successfully duplicated.\n");
            
            ADVAPI32$RevertToSelf();
            
            // register the token with the current beacon session
            if(!BeaconUseToken(duplicatedToken)) {
                BeaconPrintf(CALLBACK_ERROR, "[!] Error applying the token to the current context.\n");
!                goto cleanup; <<< leaks handle to threadToken and duplicatedToken
            }
...
            // clean up so there's not an additional token leak
            KERNEL32$CloseHandle(threadToken);
            KERNEL32$CloseHandle(duplicatedToken);
            KERNEL32$DisconnectNamedPipe(serverPipe);
            KERNEL32$CloseHandle(serverPipe);

goto cleanup;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions