首页 > 系统相关 >滴水逆向笔记系列-win32总结9-61.CE使用-62.ShellCode_远程线程注入

滴水逆向笔记系列-win32总结9-61.CE使用-62.ShellCode_远程线程注入

时间:2024-03-17 17:36:20浏览次数:15  
标签:rsi 18 地址 dll win32 61 62 线程 NULL

第六十一课 CE使用

下载完CE后用ce自带的小作业练练

1.第二题

先打开进程
image.png
First scan搜索100,发现有很多100,我们先让右边程序Hit me,然后Next scan搜索96,发现已经搜出来了,正常数据会很多,就需要继续改继续搜,最后点击下面value修改为1000即可
image.png

2.第三题

先New Scan搜索小于500的,
image.png
点击右边的Hit me,看到-7,Next Scan搜索减了7的数值,发现还有三个,
image.png
再点一次,Next Scan搜索减了5的数值,最后和第二题一样修改数值即可500
image.png

3.第四题

这题主要就是类型的选择
image.png

4.第五题

找到数据在哪后点这里可以看哪个地址对该数值进行写入
image.png

image.png

5.第六题

看到上两行代码可以发现rdx其实是由325AD0地址里面的值决定的,eax的值就是被赋值到rdx地址里面
image.png
所以我们直接去看325AD0地址里面的值
image.png

6.第七题

这里找到减一的代码后需要把他修改代码的意义,比如修改成加一
修改代码时需注意硬编码的数量要保持不变,我们需要修改的代码如果比原来少,我们可以使用nop代替,需要修改的代码如果比原来多,我们可以使用jmp到其他地址执行我们的代码然后再jmp回来
image.png

7.第八题(重点)

先找出数据的地址,看一下代码,eax应该就是存放数值的寄存器,数据存放到[rsi+18]这个地址,我们想找到数据存放的基址
image.png
看下面寄存器信息可以看到rsi为015960F0,搜一下这个地址存放的地址,发现有两个,跟踪这两个地址的访问情况,可以看到01613B10在点击改变数值是有访问记录的,说明这个地址才是我们需要的image.png
可以看到语句是mov rsi,[rsi],rsi015960F0就是[rsi]01613B10这个地址放的,可以看到没有偏移,所以我们继续搜01613B10是谁放的
image.png
mov rsi,[rsi+18] ,rsi01613B10是[rsi+18]069AB6C8地址存放的,再跟踪一下[rsi+18]的rsi是哪里存放的
:为什么我是跟踪后面的rsi,因为mov rsi,[rsi+18]意思就是把[rsi+18]的数值赋值给rsi,我们上面搜索的是01613B10是谁赋值的,所以01613B10就是rsi,[rsi+18]就是我们想搜的地址,谁存放的rsi
image.png
可以看到有10的偏移,所以我们搜索015FB280-10,最后得出基址100325B00,基址就是绿色的,也是一个具体的值
image.png
所以得出最后的思路公式[[[[100325B00]+10]+18]]+18
image.png

第六十二课 ShellCode_远程线程注入

1.ShellCode

ShellCode其实就是放在哪都可以执行的硬编码。
因为可能会有两种情况:

  • 硬编码里含有全局变量,当硬编码放到其他进程后,由于全局变量是写死的绝对地址,所以那个绝对地址在其他进程中是找不到
  • 硬编码里的函数如果直接使用,在反汇编里面其实是call [0x123456],这个0x123456就是iat表,但是当这个硬编码拿到其他进程中时,他可能在0x123456找不到iat表,函数也就用不了了

2.远程线程注入

HANDLE WINAPI CreateThread(				
    LPSECURITY_ATTRIBUTES lpThreadAttributes,				
    SIZE_T dwStackSize,				
    LPTHREAD_START_ROUTINE lpStartAddress,				
    LPVOID lpParameter,				
    DWORD dwCreationFlags,				
    PDWORD lpThreadId				
    );				
				
HANDLE WINAPI CreateRemoteThread(				
    HANDLE hProcess,				
    LPSECURITY_ATTRIBUTES lpThreadAttributes,				
    SIZE_T dwStackSize,				
    LPTHREAD_START_ROUTINE lpStartAddress,				
    LPVOID lpParameter,				
    DWORD dwCreationFlags,				
    LPDWORD lpThreadId				
    );			

目标:把模块(dll,exe)通过进程B写入到进程A里面
image.png
思路:进程B使用CreateRemoteThread函数在进程A远程创建一个线程,这个线程使用
LoadLibrary()函数加载模块
问题:这里有四个问题

  • 一个是远程线程调用函数CreateRemoteThread函数的调用函数是有格式需要的
  • 一个是线程函数的地址怎么获取
  • 一个是线程函数的参数(即我们想要加载的模块名字的字符串地址怎么获取
  • dll加载进进程A后,我们怎么得到dll的首地址,因为使用dll我们需要dll的地址

回答问题

  • LoadLibrary()的函数格式刚好和要求的一样(DWORD和HMODULE一样)
线程函数结构:	
typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(					
    LPVOID lpThreadParameter					
    );					

LoadLibarary()的函数格式:
HMODULE	WINAPI LoadLibraryA(					
    LPCSTR lpLibFileName					
    );	
  • LoadLibrary()函数的地址在进程A和进程B是一样的
  • 模块名字的字符串地址就直接在进程B中写入模块名字字符串顺便获取地址,使用函数VirtualAllocEx()WriteProcessMemory()
  • HINSTANCE hModule = LoadLibrary("InjectDll.dll"); ,自己加载dll我们可以使用变量接收,等待线程函数结束, 获取线程退出码,即LoadLibrary的返回值,即dll的首地址,因为我们自己写线程函数的时候退出码就是我们返回的值
  • 最后释放为DLL名字申请的空间VirtualFreeEx() 关闭句柄CloseHandle()

代码

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

BOOL SetDebugPrivilege()
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tokenPrivileges;
	BOOL result = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	if (!result)
		return FALSE;

	result = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPrivileges.Privileges[0].Luid);
	if (!result)
	{
		CloseHandle(hToken);
		return FALSE;
	}

	tokenPrivileges.PrivilegeCount = 1;
	tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	result = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(tokenPrivileges), NULL, NULL);
	CloseHandle(hToken);

	return result;
}

int main()
{
	/*if (!SetDebugPrivilege())
	{
		printf("无法设置调试特权\n");
		return 0;
	}*/


	//获取进程id
	HANDLE Hpid = ::OpenProcess(PROCESS_ALL_ACCESS, NULL, 3292);
	//获取LoadLibarary地址
	HMODULE LibHandle = LoadLibrary("kernel32");
	if (LibHandle == NULL) {
		printf("无法加载kernel32模块\n");
		return 0;
	}
	else
	{
		printf("加载模块成功\n");
	}
	FARPROC ProcAdd = GetProcAddress(LibHandle, "LoadLibraryA");
	if (ProcAdd == NULL) {
		printf("无法获取LoadLibrary地址\n");
		return 0;
	}
	else
	{
		printf("获取地址成功\n");
	}
	//写入进程A LoadLibarary字符串并获取地址
	LPVOID Buffer = VirtualAllocEx(Hpid, NULL, 256, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (Buffer == NULL) {
		printf("申请空间失败,可能需要重定位\n");
		return 0;
	}
	else
	{
		printf("申请空间成功\n");
	}
	TCHAR CharBuffer[256] = "injectDll.dll";
	DWORD CharAddress = WriteProcessMemory(Hpid, Buffer, CharBuffer, 256, NULL);

	//远程创建线程
	HANDLE HRemoteThread = ::CreateRemoteThread(Hpid, NULL, 0, (LPTHREAD_START_ROUTINE)ProcAdd, Buffer, 0, NULL);
	printf("错误码: %d\n", GetLastError());
	//WaitForSingleObject(HRemoteThread, INFINITE);
	//获取线程退出码
	DWORD ExitCode;
	GetExitCodeProcess(HRemoteThread, &ExitCode);

	getchar();
}

标签:rsi,18,地址,dll,win32,61,62,线程,NULL
From: https://www.cnblogs.com/xiaoxin07/p/18078832

相关文章

  • 滴水逆向笔记系列-win32总结10-63.IAT HOOK-64.Inline HOOK
    第六十三课IATHOOK这节课得把前面PE部分的IAT表复习好,再来做就简单多了1.IATHOOK是什么其实就是找到IAT表的位置再换成自己定义的函数,只是我们替换的函数需要和原函数的结构保持一直,比如我们要HOOKMessagebox函数,那么我们需要定义一个MyMessagebox函数,他的结构应该与Messa......
  • 滴水逆向笔记系列-win32总结7-57.进程创建-58.挂起方式创建进程
    第五十七课win32进程创建1.进程创建的过程父进程创建子进程,父进程挂了子进程不会挂0x00程序、imagebuffer、进程的关系程序就是一个普通的二进制文件;imagebuffer就是程序拉伸到内存后的二进制文件,但是没有线程去执行他,进程则是有线程去运行这个imagebuffer0x01过程......
  • 【洛谷 P8661】[蓝桥杯 2018 省 B] 日志统计 题解(滑动窗口+优先队列+双端队列+集合)
    [蓝桥杯2018省B]日志统计题目描述小明维护着一个程序员论坛。现在他收集了一份“点赞”日志,日志共有NNN行。其中每一行的格式是tsid,表示在......
  • lc962 最大宽度坡
    给定数组A[n],如果i<j,并且A[i]<=A[j],则称坡的宽度为j-i。求A中坡的最大宽度,如果不存在,返回0。2<=n<=50000;0<=A[i]<=50000二维偏序问题,先按元素值排序去掉一维,将符合条件的元素加入集合,然后在集合中根据第二维找最优答案。classSolution{public:intmaxWidthRamp(vecto......
  • 滴水逆向笔记系列-win32总结4-50.创建线程-51.线程控制_CONTEXT结构
    第五十课win32创建线程1.进程与线程程序就是在硬盘里还没跑起来的二进制文件,进程就是已经运行中的程序,一个进程至少有一个线程,比如一个正在举行的活动需要几十个人帮忙干活,进程就是那个活动,线程就是那几十个人一个线程启动是需要占用一个cpu的一个新线程也会创建一个新堆......
  • 滴水逆向笔记系列-win32总结5-52.临界区-53.互斥体
    第五十二课win32临界区1.线程安全问题其实就是多个线程同时对一个资源(即全局变量等)进行操作2.临界区设计图临界区的使用1、创建CRITICAL_SECTION: CRITICAL_SECTIONcs; 2、在使用前进行初始化 InitializeCriticalSection(&cs); ......
  • 滴水逆向笔记系列-win32总结1-43.宽字节-44.事件_消息_消息处理函数
    第四十三课win32宽字节1.编码0x00.ASCII码1、ASCII码使用指定的7位或8位二进制数组合来表示128或256种可能的字符2、标准ASCII码使用7位二进制数来表示所有的大写和小写字母,数字0到9、标点符号,以及在美式英语中使用的特殊控制字符。3、扩展ASCII码允许将......
  • 滴水逆向笔记系列-win32总结2-45.esp寻址_定位回调函数-46.子窗口_消息处理函数-47.资
    第四十五课win32esp寻址_定位回调函数自己vs编译的exe入口函数好像和课程视频哩的vc6不一样,没办法跟着视频走,可以用课件里给的作业exe勉强跟着视频学,前面的都差不多,课件下载地址:https://www.bcdaren.com/video/videoPlay/3303185150621818881.win32应用程序入口识别没加过壳......
  • 滴水逆向笔记系列-win32总结3-48.提取图标_修改标题-49.通用控件_实现LoadPE
    第四十八课win32提取图标_修改标题1.添加图标a,.右键添加icon时不要直接新建,导入b.加载图标:::infoHICONhIcon;hIcon=LoadIcon(hAppInstance,MAKEINTRESOURCE(IDI_ICON));hAppInstance 应用程序句柄IDI_ICON 图标编号MAKEINTRESOURCE 用这个宏的主要原因......
  • 服务器端jupyter notebook映射到本地浏览器的操作【文章转自https://www.cnblogs.com/
    这篇文章转自主要介绍了服务器端jupyternotebook映射到本地浏览器的操作,做科研经常有这样的需求:即需要借助服务器的计算资源,本地编辑的工程文件需要每次都传到服务器才能运行。jupyter是较好的交互式编辑工具,有没有一种方式可以在jupyter上编辑属于服务器的文件呢?这就引出了我们......