ring3 x32挂起进程注入原理.
一丶挂起进程注入简介与前言
挂起进程其实就是在创建进程的时候不让其先执行.然后获取它的EIP 将它的EIP变成我们ShellCode所在的内存.进行执行.不难.
主要分为几步:
1.以CREATE_SUSPENDED标志挂起创建一个你想注入的进程
2.获取这个进程的上下文环境 GetThreadContext 64位下使用Wow64GetThreadContext 请注意.CONTEXT结构还是同一个.使用64的会出错.亲测.(EIP注入的时候测试过.不相信可以去试试)
3.定义自己的ShellCode. ShellCode主要作用就是注入指定路径下的DLL
4.修复ShellCode 因为毕竟ShellCode地址是绝对的所以修复下即可.
5.在目标进程中申请远程可读写执行内存.并且将修复好的ShellCode写入到目标进程
6.将EIP修改为可读写内存的地址.恢复线程则会调用到我们申请地址位置处开始执行.
7.释放一系列资源.
综上所述.其实没有难点.挂起进程注入主要的核心思想就是 挂起进程修改EIP为我们ShellCode起始位置.然后进行调用即可.
这里核心主要是ShellCode
ShellCode如下:
UCHAR g_ShellCode[] = {
0x68,0x00,0x00,0x00,0x00, //push Context.EIP 需要修复
0x60, //puad
0x9C, //pushfd
0xE8, 0x00, 0x00, 0x00, 0x00, //call $0 代码重定位
0x5B, //pop ebx
0x83, 0xEB,0x00, //sub ebx,0 可加可不加
0x8D, 0x4B,0x12, //lea ecx,dword ptr ds:[ebx + 0x10] 定位到ShellCode下方获取DLLpath地址
0x51, //push ecx
0xB8, 0x00,0x00,0x00,0x00, //mov eax,LoadLibraryA 修复LoadLibraryA的地址
0xFF,0XD0, //call eax 为啥使用Mov reg,address call reg. 自己去坑吧.
0x9D, //popfd
0x61, //popad
0xC3, //ret
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
ShellCode主要知识点有三个
1.保存contex.EIP
2.重定位LoadLibrary的参数
3.重定位LoadLibrary的地址
下面主要针对这几点讲解.
二丶ShellCode核心讲解.
2.1 保存Contex.EIP
首先挂起进程注入. 你通过CONTEXT 这个结构可以获取 目标进程EIP.但是你要想办法执行完ShellCode之后跳转回去.
所以这里我使用了一个简单的方法
push Address
ret
这个方式是利用堆栈.以及ret指令来进行返回的. 当我们保存了原始地址.然后ret的时候.ret会把我们push的地址当做返回地址来执行.
2.2 DLL路径重定位
我们正常来说.调用LoadLibraryA/W的时候.都会进行参数压栈进而进行调用.
如:
push xxxx地址 (地址里面是个DLL路径)
call LoadLibraryA; 调用LoadLibrary
而为了方便我直接代码重定位.直接将ShellCode尾部写入我们的DLL路径.
call $0:
pop ebx
使用这两句可以得到ebx当前指令指定的EIP的地址. 直接当前 EIP + xxx偏移(偏移是你写DLL路径的位置的偏移) 就是我们的参数地址.
2.3 LoadLibrary的重定位
当你直接使用 Call的方式调用LoadLibrary的时候.你还需要计算偏移.各种等等.
但是这种不需要的.为啥. 因为Windows在启动后 kernel32的基址已经固定了.任何程序启动都会默认加载 kernel32的.所以直接使用LoadLibrary当地址即可.
但是你使用Call的方式 (call LoadLibrary) 你还需要计算你的ShellCode 与LoadLibrary的偏移.所以我们直接使用寄存器来做.
mov reg,LoadLibrary
call reg
reg代表任意通用寄存器.
此时我们的ShellCode就可以正常运行了.通过以上步骤就可以开始运行了.
三丶 全部C++代码.拷贝即可使用.
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
using namespace std;
UCHAR g_ShellCode[] = {
0x68,0x00,0x00,0x00,0x00, //push Context.EIP 需要修复
0x60, //puad
0x9C, //pushfd
0xE8, 0x00, 0x00, 0x00, 0x00, //call $0 代码重定位
0x5B, //pop ebx
0x83, 0xEB,0x00, //sub ebx,0 可加可不加
0x8D, 0x4B,0x12, //lea ecx,dword ptr ds:[ebx + 0x10] 定位到ShellCode下方获取DLLpath地址
0x51, //push ecx
0xB8, 0x00,0x00,0x00,0x00, //mov eax,LoadLibraryA 修复LoadLibraryA的地址
0xFF,0XD0, //call eax 为啥使用Mov reg,address call reg. 自己去坑吧.
0x9D, //popfd
0x61, //popad
0xC3, //ret
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //填写为DLL路径
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //不够可以继续添加
};
/*
1.挂起创建Explorer
2.创建ShellCode
3.获取上下文环境
4.申请远程内存 写入ShellCode
5.回去上下文环境
ShellCode 可以写定位LoadLibrary 然后进行调用
*/
//1.挂起创建 Explorer
PPROCESS_INFORMATION StartSuspendProcess(string SuspendProcessName,char szComand[])
{
BOOL bRet = FALSE;
PPROCESS_INFORMATION pi = nullptr;
pi = new PROCESS_INFORMATION;;
if (pi == nullptr)
{
return nullptr;
}
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
//创建挂起进程
bRet = CreateProcess(
SuspendProcessName.c_str(),
szComand,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&si,
pi);
if (bRet == FALSE)
{
return nullptr;
}
return pi;
}
//申请远程内存
LPVOID lpExRemoteAllocMemory(HANDLE hProcess,DWORD flAllocation,DWORD Protected)
{
LPVOID lpBuffer = nullptr;
lpBuffer =
VirtualAllocEx(hProcess,
0,
0x1000,
flAllocation,
Protected
);
if (lpBuffer != nullptr)
return lpBuffer;
return nullptr;
}
//写入ShellCode到远程内存
DWORD lpWriteRemoteMemory(HANDLE hProcess, LPVOID lpExRemoteMemory)
{
//将ShellCode写入到远程内存
DWORD dwRet = 0;
SIZE_T siWriteBytes;
if (hProcess == 0)
return 0;
if (lpExRemoteMemory == nullptr)
return 0;
dwRet = WriteProcessMemory(
hProcess,
lpExRemoteMemory,
g_ShellCode,
sizeof(g_ShellCode) / sizeof(g_ShellCode[0]),
&siWriteBytes);
return dwRet;
}
//修复ShellCode,并且将DLL路径写入到ShellCode位置.
DWORD FixShellCode(DWORD dwContexEip,char* DllPath)
{
/*
纵观全局数据区,ShellCode修复的位置有2处
1.首先要修复原Context的EIP. 这样RET之后直接跳转回去.
2.要修复LoadLibrary的地址. 因为Kernel32是直接加载的都是属于内存映射.所以虚拟地址一样.直接获取填入即可.
不用修复DLLpath. 因为自动进行代码重定位写法了.
*/
//1.修复EIP
__try
{
*(DWORD*)(char*)&g_ShellCode[1] = dwContexEip;
//2.修复LodLibrary地址.
//修复
*(DWORD*)(char*)&g_ShellCode[21] = (DWORD)LoadLibraryA;
//将DLL内容拷贝到ShellCode存放路径处
memcpy((char*)&g_ShellCode[30], DllPath, strlen(DllPath) + 1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
//出错了.
}
return 1;
}
void run()
{
DWORD dwRet = 0;
LPVOID lpStartRemoteAddress = nullptr;
//1.挂起创建进程
PPROCESS_INFORMATION pi = nullptr;
char szCmd[] = "";
pi = StartSuspendProcess("C:\\Windows\\SysWOW64\\explorer.exe",szCmd);
if (!pi)
{
return;
}
//2.获取进程上下文环境.
CONTEXT MyContext = { 0 };
MyContext.ContextFlags = CONTEXT_FULL;
dwRet = GetThreadContext(pi->hThread, &MyContext);
if (!dwRet)
{
return;
}
//3.修复ShellCode的值.并且写入自己的DLL路径
char szDllPath[] = "填入你的DLL路径.如: C:\\xxx.dll";
dwRet = FixShellCode(MyContext.Eip,szDllPath);
//4.申请远程内存
lpStartRemoteAddress = lpExRemoteAllocMemory(pi->hProcess, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpStartRemoteAddress == nullptr)
{
return ;
}
//5.将ShellCode写入到内存中
dwRet = lpWriteRemoteMemory(pi->hProcess, lpStartRemoteAddress);
//6.恢复进程启动,修改EIP为我们的ShellCode
MyContext.Eip = (DWORD)lpStartRemoteAddress;
SetThreadContext(pi->hThread, &MyContext);
ResumeThread(pi->hThread); //请注意这里 EIP修改为我们的ShellCode位置.还要恢复线程才会进行执行.
//释放一系列资源
VirtualFreeEx(pi->hProcess, lpStartRemoteAddress, 0x1000, MEM_RELEASE);
CloseHandle(pi->hProcess);
CloseHandle(pi->hThread);
}
int main()
{
run();
return 0;
}
ring3 x32挂起进程注入原理.的更多相关文章
- [Cuckoo SandBox]注入原理篇
1.LoadExe 接python版本 通过调用LoadExe去加载Dll进行注入 所以先看LoadExe 加载器的功能吧 通过python管道接收到 processID,ThreadID,路径 , ...
- 十种MYSQL显错注入原理讲解(二)
上一篇讲过,三种MYSQL显错注入原理.下面我继续讲解. 1.geometrycollection() and geometrycollection((select * from(select * f ...
- Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解
前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程 ...
- SQL注入原理
随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一 部分程序员在编写代码的时候,没有对用户输入数据的合法性 ...
- Mysql报错注入原理分析(count()、rand()、group by)
Mysql报错注入原理分析(count().rand().group by) 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截 ...
- sql注入--双查询报错注入原理探索
目录 双查询报错注入原理探索 part 1 场景复现 part 2 形成原因 part 3 报错原理 part 4 探索小结 双查询报错注入原理探索 上一篇讲了双查询报错查询注入,后又参考了一些博客, ...
- PHP依赖注入原理与用法分析
https://www.jb51.net/article/146025.htm 本文实例讲述了PHP依赖注入原理与用法.分享给大家供大家参考,具体如下: 引言 依然是来自到喜啦的一道面试题,你知道什么 ...
- 菜鸟详细解析Cookie注入原理
一.SQL注入原理 我以aspx为例,现在我们来研究下Cookie注入是怎么产生的,在获取URL参数的时候,如果在代码中写成Request[“id”],这样的写法问题就出现了.我先普及下科普知识,在a ...
- 回头探索JDBC及PreparedStatement防SQL注入原理
概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...
随机推荐
- 我的第一个netcore2.2 api项目搭建(一)
早早就想入门netcore,一直没下定决心,这次正好碰上项目服务变更,便想着入坑试试,边学边用. 目标: 一.api使用core版的SqlSugar,集成orm,实现快速开发 二.api使用Swagg ...
- 这两个小技巧,让我的SQL语句不仅躲了坑,还提升了1000 倍
原文: https://cloud.tencent.com/developer/article/1465618 本次来讲解与 SQL 查询有关的两个小知识点,掌握这些知识点,能够让你避免踩坑以及提高查 ...
- Bootstrap4 glyphicon 移除图标 glyphicon fonts-faces 解决方案
bootrap3是支持的图标 ,4不支持 4已经移除了 收费图标,取而代之建议使用其他的,比如 https://octicons.github.com/ 和http://fontawesome.io/ ...
- Java之路---Day19(set接口)
set接口 java.util.Set 接口和 java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方 法基本一致,但是set接口中元素 ...
- Java之路---Day12(多态)
2019-10-26-22:40:09 目录: 1.多态的概念 2.多态的分类 3.实现多态的三个必要条件 4.多态的格式 5.多态成员变量的使用特点 6.多态成员方法的使用特点 7.多态的好处 8. ...
- ASP.NET Core中使用Cache缓存
ASP.NET Core中使用Cache缓存 缓存介绍: 通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性. 缓存对不经常更改的数据效果最佳. 缓存生成的数据副本的返回速度可以比从原始 ...
- vue项目的构建过程
确保已经安装了node和npm 1.安装vue-cli npm i vue-cli -g 2.安装vue-router npm i vue-router --save 3.安装vue-router n ...
- VsCode中编写python环境配置
1. VsCode中编写python环境配置 1.1. 前言 有过开发经验都知道idea一系列的软件虽然功能比较多,但比较容易卡,电脑不好还真容易上火,这里我想要入门python,还是选了款vscod ...
- 渗透 Facebook 的思路与发现
0x00 写在故事之前 身一位渗透测试人员,比起 Client Side 的弱点,我更喜欢 Server Side 的攻击,能够直接控制服务器并获得权限操作 SHELL 才爽 . 当然一次完美的渗透出 ...
- ThinkPHP5中如何实现模板完全静态化
模板完全静态化,也就是通过模板完全生成纯静态的网页,相比动态页面和伪静态页面更安全更利于SEO访问更快.相比前二者各有利弊吧,现在稍微对这三种形式的优缺点对比一下,以及在ThinkPHP5项目中实现完 ...