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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions