I wonder to set event into existed Event Log. These is code:
_ev_hndl = RegisterEventSource(NULL, L"Application");
WCHAR msg_[] = L"Hello";
if (!ReportEvent(_ev_hndl, ev_type, 1, 0, NULL, 1, 0, (LPCWSTR*)&msg_, NULL)) {
std::cout << "error: " << GetLastError() << std::endl;
}
But I get an error: 87 (invalid parameter)
The problem was close to msg parameter. Right code:
LPCTSTR strings[] = { TEXT("abcdefg") };
if (!ReportEvent(_ev_hndl, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, strings, NULL)) {...
Related
I am currently trying to implement a simple Parent PID Spoofing in Rust but I'm facing with Segfault errors / Invalid Handle when creating process whom I'm trying to spoof its parent.
I made this code and modified it a lot in order to accomplish the wanted result:
let mut sinfo = STARTUPINFOEXA::default();
let mut cb_attribute_list_size = 0;
const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: DWORD = 0x00020000;
let mut h_parent_process: HANDLE = NULL as HANDLE;
let dw_pid: DWORD = 2176;
const CMDLINE: &str = "notepad";
unsafe {
InitializeProcThreadAttributeList(
null_mut(),
1,
0,
&mut cb_attribute_list_size
);
sinfo.lpAttributeList = HeapAlloc(
GetProcessHeap(),
0,
cb_attribute_list_size
).cast();
if InitializeProcThreadAttributeList(
sinfo.lpAttributeList,
1,
0,
&mut cb_attribute_list_size
) == 0 {
eprintln!("[x] Error Initializing proccess attribute");
return Ok(());
}
h_parent_process = OpenProcess(
PROCESS_ALL_ACCESS,
0,
dw_pid // explorer.exe
);
if h_parent_process.is_null() {
eprintln!("[x] Error opening parent process");
return Ok(());
}
if UpdateProcThreadAttribute(
sinfo.lpAttributeList,
0,
0x00020000,
transmute::<PHANDLE, LPVOID>(&mut h_parent_process),
size_of::<HANDLE>(),
null_mut(),
null_mut()
) == 0 {
eprintln!("[x] Error updating PROC_THREAD_ATTRIBUTE_PARENT_PROCESS");
return Ok(());
}
let mut process_info= PROCESS_INFORMATION::default();
sinfo.StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
sinfo.StartupInfo.wShowWindow = 0;
sinfo.StartupInfo.cb = size_of::<STARTUPINFOEXA>() as u32;
if CreateProcessA(
null_mut(),
CMDLINE.to_string().as_ptr() as LPSTR,
null_mut(),
null_mut(),
0,
EXTENDED_STARTUPINFO_PRESENT,
null_mut(),
null_mut(),
&mut sinfo.StartupInfo,
&mut process_info
) == 0 {
eprintln!("[x] Error creating process");
return Ok(());
}
println!("[+] Process created: {}", process_info.dwProcessId);
DeleteProcThreadAttributeList(sinfo.lpAttributeList);
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
CloseHandle(h_parent_process);
}
I tried allocating the pAttributeList from Rust with Vec::with_capacity() or from C with HeapAlloc().
The same code works in C but I don't know what am I doing wrong in Rust. I didn't success to find an actual implementation of Parent PID Spoofing in Rust but I found some usage of UpdateProcThreadAttributeList() function.
The C source code I am trying to convert to Rust can be found here: https://www.ired.team/offensive-security/defense-evasion/parent-process-id-ppid-spoofing#ppid-spoofing
Thanks for help 🐼
---EDIT---
I reviewed the code to use Ansi version of the API, the code works fine but does not produce the result I wanted. It spawn a notepad but with no parent (System is its).
I wonder if my call to UpdateProcThreadAttributeList() is correct, I think I would have to pass the reference to the Handle of the Parent Process but HANDLE structure is a *mut c_void and LPVOID/PVOID is also a *mut c_void. I'm not quite sure if the problem reside in this thing.
As one of comment suggested, there is my C code that I try to convert:
STARTUPINFOEX sie = { sizeof(sie) };
PROCESS_INFORMATION pi;
SIZE_T cbAttributeListSize = 0;
PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = nullptr;
HANDLE hParentProcess = nullptr;
DWORD dwPid = 2176;
const char* lpCommandLine = "notepad";
InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize);
pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize);
if (NULL == pAttributeList)
{
std::cout << "[x] Error allocating heap: " << GetLastError() << std::endl;
return 0;
}
if (!InitializeProcThreadAttributeList(pAttributeList, 1, 0, &cbAttributeListSize))
{
std::cout << "[x] Error Initializing proccess attribute: " << GetLastError() << std::endl;
return 0;
}
hParentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (NULL == hParentProcess)
{
std::cout << "[x] Error opening parent process: " << GetLastError() << std::endl;
return 0;
}
if (!UpdateProcThreadAttribute(pAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParentProcess, sizeof(HANDLE), NULL, NULL))
{
std::cout << "[x] Error updating PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: " << GetLastError() << std::endl;
return 0;
}
sie.lpAttributeList = pAttributeList;
if (!CreateProcessA(NULL, const_cast<LPSTR>(lpCommandLine), NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &sie.StartupInfo, &pi))
{
std::cout << "[x] Error creating process: " << GetLastError();
return 0;
}
std::cout << "[+] Process created: " << pi.dwProcessId << std::endl;
DeleteProcThreadAttributeList(pAttributeList);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hParentProcess);
Thanks again 🐼
--LAST EDIT--
I finally figured out what I was making wrong !
During CreateProcessA() call it was trying to read the location pointed by the value of the Parent Process Handle but I was passing its value directly instead of its reference.
I edited the Rust code above. Thanks all I can close this issue.
Windows API "CreateIconFromResourceEx" not working after windows update "Update for Microsoft Windows(KB4517389)" if I uninstall this update "CreateIconFromResourceEx" will work, but there is no any official documentation regarding deprecate of "CreateIconFromResourceEx" API.
int offset = LookupIconIdFromDirectoryEx(bCursorBuff, TRUE, 0, 0, LR_DEFAULTSIZE|LR_SHARED);
if (offset != 0)
{
HICON m_hIcon = CreateIconFromResourceEx(bCursorBuff + offset, 0 , TRUE, 0x30000, 0, 0, LR_DEFAULTSIZE|LR_SHARED);
if(m_hIcon == NULL)
{
MessageBox(NULL, _T("Exception :: CreateIconFromResourceEx failde."),_T("message"),MB_OK|MB_SYSTEMMODAL);
}
}
int offset = LookupIconIdFromDirectoryEx(bCursorBuff, TRUE, 0, 0, LR_SHARED);
if (offset != 0)
{
HICON m_hIcon = CreateIconFromResourceEx(bCursorBuff + offset, bCursorBuffSize , TRUE, 0x30000, 0, 0, LR_SHARED);
if(m_hIcon == NULL)
{
MessageBox(NULL, _T("Exception :: CreateIconFromResourceEx failde."),_T("message"),MB_OK|MB_SYSTEMMODAL);
}
}
In my project I have two applications, one is Pipe Server and Pipe Client(Slave).
I am trying to send text via pipe to display it on client's console. Thus effectively creating disposable consoles.
I have tested the code by manually running the server first and then client. It runs perfectly. Then I added some code in the constructor of Server to invoke Slave.exe with pipename as arguments however the console of Slave disappears after couple seconds.
Slave's Constructor calls this function:
int OpenNamedPipe(std::string pipename)
{
pipeurl += pipename;
hPipe = CreateNamedPipe(
pipeurl .c_str(), // pipe name
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access
PIPE_TYPE_BYTE | // Datatype Byte
PIPE_WAIT, // blocking mode
1, // max. instances
outputBuffer, // output buffer size
inputBuffer, // input buffer size
0, // client time-out
NULL); // default security attribute
if (hPipe == INVALID_HANDLE_VALUE)
{
try
{
Throw_Last_Error("CreateNamedPipe failed");
}
catch (const std::runtime_error err)
{
std::cout << "Runtime Error: " << err.what();
return 0;
}
}
int timeout = 100000;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
int retnVal = CreateProcessA("Slave.exe", (LPSTR)pipename.c_str(), NULL, NULL, NULL, DETACHED_PROCESS, NULL, NULL, &si, &pi);
if (!retnVal)
{
retnVal = GetLastError();
}
if (!ConnectNamedPipe(hPipe, NULL))
{
if (!GetLastError() == ERROR_PIPE_CONNECTED)
{
try
{
Throw_Last_Error("Error while connecting to named pipe.");
}
catch (std::runtime_error err)
{
std::cout << "GLE= " << GetLastError();
Block();
return 0;
}
}
}
std::cout << "Connected to pipe.\n";
return 0;
}
In Client's main program:
int main(int argc, char *argv[])
{
AllocConsole();
std::string argstr = " ";
argstr = argv[1];
PipeClient pc(argstr);
pc.Update();
system("pause");
return 0;
}
Now I need both Server's console and Client's console to remain open for further testing but when Server is waiting for the Slave to connect to pipe, Slave's console and process closes, which shouldn't happen as I have paused it before it can return.
Edit: Pipe Client object constructor:
PipeClient(std::string pipename)
{
pipeName = pipeName + pipename;
Connect();
if (hPipe != INVALID_HANDLE_VALUE || GetLastError() != ERROR_PIPE_BUSY)
{
std::cout << "Created Pipe, GLE=" << GetLastError();
}
if (hPipe == INVALID_HANDLE_VALUE)
{
ThrowLastError("Failed to connect to named pipe.");
}
}
int Connect()
{
while (true)
{
WaitNamedPipeA(pipeName.c_str(), NMPWAIT_WAIT_FOREVER);
hPipe = CreateFileA(
pipeName.c_str(),
GENERIC_READ |
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hPipe != INVALID_HANDLE_VALUE || GetLastError() != ERROR_PIPE_BUSY)
{
std::cout << "Created Pipe, GLE=" << GetLastError();
break;
}
}
return 0;
}
Class Fields:
DWORD inputBuffer = 256;
DWORD outputBuffer = 256;
HANDLE hPipe;
std::string pipeName = "\\\\.\\pipe\\";
char * testpipename = "\\\\.\\pipe\\namedpipe";
Github repo:https://github.com/BhayanakMoth2/PipedConsole
So I fixed the problem, I was not using the CreateProcess function properly.
This should be the fixed function call:
std::string cmd = "Slave.exe " + pipename;
int retnVal = CreateProcessA("Slave.exe", (LPSTR)cmd.c_str(), NULL, NULL, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
I misread the documentation. And the reason Slave.exe was crashing because the arguments were not being passed properly and so when it reached:
argstr = argv[1]
it crashed silently. The second argument in CreateProcessA() fixes this problem by properly passing the arguments.
This is the first time calling Sleep_Detection() which is a function that includes RegisterClass():
//some codes here...
Execute_Command(0);
Sleep_Detection(); **//First time calling, no problem**
This is the second time calling Sleep_Detection() but it's now calling from inside of the SleepDetectionProc() callback function, the error occurred here.
I used GetLastError() and here I got an error code of 1410 which means "ERROR_CLASS_ALREADY_EXISTS".
LRESULT _stdcall SleepDetectionProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_POWERBROADCAST)
{
if (wParam == PBT_APMRESUMESUSPEND)
{
cout << "System restored" << endl;
Execute_Command(0);
Sleep_Detection(); **//Second time calling, error code 1410**
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
This is the Sleep_Detection() function:
void Sleep_Detection(void)
{
WNDCLASS WindowClass = { 0 };
WindowClass.lpfnWndProc = SleepDetectionProc;
WindowClass.lpszClassName = (L"Sleep detection");
if (!GetClassInfo(WindowClass.hInstance, WindowClass.lpszClassName, &WindowClass))
{
if (!RegisterClass(&WindowClass))
{
cout << "Cannot register class (Error Code: " << GetLastError() << ")" << endl;
exit(EXIT_FAILURE);
}
else
cout << "registered" << endl;
}
else
cout << "Class already exists" << endl;
HWND WinHandle = NULL;
if (!FindWindow(WindowClass.lpszClassName, ConsoleTitle))
{
if ((WinHandle = CreateWindow(L"Sleep detection", L"", 0, 0, 0, 0, 0, NULL, NULL, NULL, 0)) == NULL)
{
cout << "Cannot create window (Error Code: " << GetLastError() << ")" << endl;
exit(EXIT_FAILURE);
}
else
cout << "window created" << endl;
}
else
cout << "Window already exists" << endl;
int upRes;
MSG Message;
while (upRes = GetMessage(&Message, WinHandle, 0, 0))
{
if (upRes == -1)
{
cout << "An error occurred when getting window messages (Error Code: " << GetLastError() << endl;
exit(EXIT_FAILURE);
}
else
{
cout << "Got Message!" << endl;
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
}
So I basically called Sleep_Detection() twice and it also called the RegisterClass() function inside. I guess the error could be related to overwritten the RegisterClass()?
WNDCLASS WindowClass = { 0 };
WindowClass.lpfnWndProc = SleepDetectionProc;
WindowClass.lpszClassName = (L"Sleep detection");
WindowClass.hInstance is zero, which will cause GetClassInfo() to fail even if the window class already exists, because the value of NULL for the parameter hInstance is reserved for classes defined by the system, which is stated at the MSDN page:
hInstance
A handle to the instance of the application that created the class. To
retrieve information about classes defined by the system (such as
buttons or list boxes), set this parameter to NULL.
So RegisterClass will always be attempted, which of course fails on the 2nd try.
To correct the error, initialize WindowClass.hInstance like this:
WindowClass.hInstance = GetModuleHandle(NULL); // get hInstance of current process
If the code is called from a DLL, replace GetModuleHandle(NULL) with the handle of that DLL. By the way, HMODULE is interchangeable with HINSTANCE, that is the base address of the module.
I'm trying to convert wide char into multi-byte. It's only on yje myfile part. The rest works fine.I can't use wofstream because I am using ofstream in several places, so I am left with this.
void PrintBrowserInfo(IWebBrowser2 *pBrowser) {
BSTR bstr;
pBrowser->get_LocationURL(&bstr);
std::wstring wsURL;
wsURL = bstr;
size_t DSlashLoc = wsURL.find(L"://");
if (DSlashLoc != wsURL.npos)
{
wsURL.erase(wsURL.begin(), wsURL.begin() + DSlashLoc + 3);
}
DSlashLoc = wsURL.find(L"www.");
if (DSlashLoc == 0)
{
wsURL.erase(wsURL.begin(), wsURL.begin() + 4);
}
DSlashLoc = wsURL.find(L"/");
if (DSlashLoc != wsURL.npos)
{
wsURL.erase(DSlashLoc);
}
wprintf(L"\n URL: %s\n\n", wsURL.c_str());
char LogURL = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, wsURL.c_str(), -1, NULL, 0, NULL, NULL);
myfile << "\n URL:" << LogURL;
SysFreeString(bstr);
}
void EnumExplorers() {
CoInitialize(NULL);
SHDocVw::IShellWindowsPtr spSHWinds;
IDispatchPtr spDisp;
if (spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) == S_OK) {
long nCount = spSHWinds->GetCount();
for (long i = 0; i < nCount; i++) {
_variant_t va(i, VT_I4);
spDisp = spSHWinds->Item(va);
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
if (spBrowser != NULL) {
PrintBrowserInfo((IWebBrowser2 *)spBrowser.GetInterfacePtr());
spBrowser.Release();
}
}
} else {
puts("Shell windows failed to initialise");
}
}
You're using WideCharToMultiByte wrong. You need to pass it a string buffer to receive the converted string. Using NULL and 0 as parameters as you have done will return the required size of the result string.
int length = WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, wsURL.c_str(), -1, NULL, 0, NULL, NULL);
std::string LogURL(length+1, 0);
int result = WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, wsURL.c_str(), -1, &LogURL[0], length+1, NULL, NULL);
You should check result for a non-zero value to make sure the function worked correctly.