第六十一课 CE使用
1.第二题
先打开进程
First scan搜索100,发现有很多100,我们先让右边程序Hit me,然后Next scan搜索96,发现已经搜出来了,正常数据会很多,就需要继续改继续搜,最后点击下面value修改为1000即可
2.第三题
先New Scan搜索小于500的,
点击右边的Hit me,看到-7,Next Scan搜索减了7的数值,发现还有三个,
再点一次,Next Scan搜索减了5的数值,最后和第二题一样修改数值即可500
3.第四题
4.第五题
找到数据在哪后点这里可以看哪个地址对该数值进行写入
5.第六题
看到上两行代码可以发现rdx其实是由325AD0地址里面的值决定的,eax的值就是被赋值到rdx地址里面
所以我们直接去看325AD0地址里面的值
6.第七题
这里找到减一的代码后需要把他修改代码的意义,比如修改成加一
注:修改代码时需注意硬编码的数量要保持不变,我们需要修改的代码如果比原来少,我们可以使用nop代替,需要修改的代码如果比原来多,我们可以使用jmp到其他地址执行我们的代码然后再jmp回来
7.第八题(重点)
先找出数据的地址,看一下代码,eax应该就是存放数值的寄存器,数据存放到[rsi+18]这个地址,我们想找到数据存放的基址
看下面寄存器信息可以看到rsi为015960F0,搜一下这个地址存放的地址,发现有两个,跟踪这两个地址的访问情况,可以看到01613B10在点击改变数值是有访问记录的,说明这个地址才是我们需要的
可以看到语句是mov rsi,[rsi]
,rsi015960F0就是[rsi]01613B10这个地址放的,可以看到没有偏移,所以我们继续搜01613B10是谁放的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
可以看到有10的偏移,所以我们搜索015FB280-10,最后得出基址100325B00,基址就是绿色的,也是一个具体的值
所以得出最后的思路公式[[[[100325B00]+10]+18]]+18
第六十二课 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里面
思路:进程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