bypass 随机基址

//有漏洞 并且开启了随机基址的程序 溢出点VerifyPassword返回地址
#include<windows.h>
#include<tchar.h>
#include <iostream>
#define PASSWORD "1234"
void* VerifyPassword(byte* pRet, void* pszPassword, int nSize) {
    char szBuffer[50] = { 0 };
    *pRet = strcmp(PASSWORD, (char*)pszPassword);
    return memcpy(szBuffer, pszPassword, nSize); //通过拷贝溢出
}
int _tmain(int argc, _TCHAR* argv[]) {
    void* pszPassword = NULL;
    int   nFileSize = 0;
    byte  bFlag = FALSE;
    FILE* fp;
    LoadLibraryA("user32.dll");
    if (fopen_s(&fp, "password.txt", "rb")) {
        MessageBoxA(NULL, "打开文件失败", "error", NULL);
        return 0;
    }
    fseek(fp, 0, SEEK_END);
    nFileSize = ftell(fp);
    rewind(fp);
    pszPassword = ZeroMemory(malloc(nFileSize), nFileSize);
    fread(pszPassword, nFileSize, 1, fp);
    VerifyPassword(&bFlag, pszPassword, nFileSize);
    if (bFlag) printf("密码错误\n");
    else       printf("密码正确\n");
    fclose(fp);
    system("pause");
    return 0;
}

此次绕过随机基址的方法是覆盖RVA 首先看基址为FE0000 在函数返回前 看返回地址基址是可以变化的 但是他的RVA是无法改变的 119e 所以我们只要覆盖两个字节的rva就达到了执行我们代码的目的

 看上图的eax寄存器 就是我们memcpy的返回值 也就是拷贝缓冲区的首地址 我们只要精心构造文件 让他刚好覆盖RVA那两个字节的同时 最后拼接好的地址里的指令是call eax或jmp eax,push eax ret这样的指令 也就达到了执行shellcode的条件

由于我重新运行了程序 所以基址到00EE0000了 必须在本模块查找我们需要的指令 FFE0(jmp eax)

 找到指令 rva为1122 

 构造文件用1122替换函数返回地址的rva

 再次走到函数返回的地方 会返回到我们填写的地址去执行

 eax就是缓冲区首地址 

 于是就成功的跑到我们预想的位置执行代码了

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值