Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several handle leaks in KohClient.c #3

Open
JohnLaTwC opened this issue Jul 7, 2022 · 0 comments
Open

Several handle leaks in KohClient.c #3

JohnLaTwC opened this issue Jul 7, 2022 · 0 comments

Comments

@JohnLaTwC
Copy link
Contributor

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;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant