OD: Exploit Me - Overwrite Return Address
修改邻接变量的方法对代码环境限制比较多,更通用、更强大的方法是修改 EBP、返回地址等状态值。
为了方便调试,修改之前的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h> #define PASSWORD "1234567" int verify_password(char *password)
{
int authenticated=0x03050709;
char buffer[]; // add local buf to be overflowed
authenticated=strcmp(password,PASSWORD);
strcpy(buffer, password); // overflow here
return authenticated;
} int main()
{
int valid_flag=;
char password[];
if(!freopen("password.txt","r",stdin)) // 非打印字符不便于从console输入,故 redirect stdin
//FILE *fp;
//if(!(fp=fopen("password.txt","rw+")))
{
printf("file open error!\n");
exit();
}
scanf("%s",password);
//fscanf(fp,"%s",password);
printf("password input: %s\n",password);
valid_flag=verify_password(password);
if(valid_flag){
printf("Incorrect password!\n\n");
}
else
{
printf("Congratulation! You have passed the verification!\n\n");
}
//fclose(fp);
return ;
}
在 password.txt 中存储内容为 abcdefg 时,OD 调试 exp_me.exe,执行完第 12 行 strcpy 后的栈帧如下图所示:

如上图,此时栈帧中 authenticated 的值(0x0012FAE8)为 1,表示验证未通过。EBP : 0x0012FAEC,前栈帧 EBP : 0x0012FF48,返回地址 : 0x0040ECD8。
0040ECCC |. 8D95 FCFBFFFF LEA EDX,DWORD PTR SS:[EBP-]
0040ECD2 |. PUSH EDX
0040ECD3 |. E8 2D23FFFF CALL exp_me.
0040ECD8 |. 83C4 ADD ESP,
0040ECDB |. FC MOV DWORD PTR SS:[EBP-],EAX
0040ECDE |. 837D FC CMP DWORD PTR SS:[EBP-],
0040ECE2 |. 0F JE SHORT exp_me.0040ECF3
0040ECE4 |. AC404200 PUSH OFFSET exp_me.??_C@_0BG@GFGB@Incorr>; /format = "Incorrect password! "
0040ECE9 |. E8 F225FFFF CALL exp_me.printf ; \printf
0040ECEE |. 83C4 04 ADD ESP,4
0040ECF1 |. EB 0D JMP SHORT exp_me.0040ED00
0040ECF3 |> 68 6C404200 PUSH OFFSET exp_me.??_C@_0DD@FPBB@Congra>; /format = "Congratulation! You have passed the verification! "
0040ECF8 |. E8 E325FFFF CALL exp_me.printf ; \printf
0040ECFD |. 83C4 04 ADD ESP,4
0040ED00 |> 33C0 XOR EAX,EAX
0040ED02 |. 5F POP EDI
0040ED03 |. 5E POP ESI
从上面的反汇编代码可以看到,0x0040ECD8 处的代码对应源码第 30 行后恢复栈帧处,如果能将此时的返回地址覆盖为 0x0040ECF3,就能跳过错误验证流程,直接执行源码中第 36 行的 else 分支,进入验证正确后的执行流程。
用 UltraEdit 将 password.txt 修改为如下内容:

注意,CPU 为 Little_Endian 模式,最后的四字节返回地址(0x0040ECF3)要反写成 E3 EC 40 00
在返回地址之前的前栈帧地址 0x0012FF48 不能写为 48 FF 12 00,因为这里的 00 会被 scanf 当作截断符中止读取,导致内容读取不够,覆盖返回地址失败(只能覆盖到 EBP)。
修改 password.txt 后,OD 调试结果如下:

紧接着出现如下错误,因为 EBP 覆盖成了错误的 0xAA12FF48 而不是 0x0012FF48,导致栈帧不平衡。
这个问题留着以后再学习吧,今天到此了,睡觉去(2014-3-31 23:31:55)。

OD: Exploit Me - Overwrite Return Address的更多相关文章
- OD: Exploit Me - Overwrite Nearby Varible
实验代码: #include<stdio.h> #include<string.h> #define PASSWORD "1234567" int veri ...
- Multi-tasking RTOS for microprocessors with limited memory by saving only a single return address per task during context switching
A real-time operating system (RTOS) for use with minimal-memory controllers has a kernel for managin ...
- 栈帧的内部结构--动态返回地址(Return Address)
每个栈帧中包含: 局部变量表(Local Variables) 操作数栈(Opreand Stack) 或表达式栈 动态链接 (Dynamic Linking) (或指向运行时常量的方法引用) 动态返 ...
- OD: Exploit Me - Inject Instruction
修改之前的代码: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<windo ...
- OD: Shellcode / Exploit & DLL Trampolining
看到第五章了. 标题中 Dll Tramplining(跳板)名字是从如下地址找到的,写的很好: http://en.wikipedia.org/wiki/Buffer_overflow#The_ju ...
- BUFFER OVERFLOW 10 Vulnerability & Exploit Example
SRC= http://www.tenouk.com/Bufferoverflowc/Bufferoverflow6.html THE VULNERABLE AND THE EXPLOIT W ...
- OD: ASLR
ASLR,Address Space Layout Randomization,通过加载程序的时候不再使用固定的基址,从而干扰 shellcode 定位的一种保护机制,包括映像随机化.堆栈随机化.PE ...
- Detecting a return-oriented programming exploit
A method and apparatus for detecting a Return-Oriented Programming exploitation. At a computer devic ...
- OD: DEP - Ret2Libc via VirtualProtect() & VirtualAlloc()
一,通过 VirutalProtect() 修改内存属性绕过 DEP DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中 ...
随机推荐
- xAML中一些控件的用法学习
首先,介绍一些比较简单的设计,这些可以直接通过拖拽实现.如下例子: <Window x:Class="wpf1.MainWindow" xmlns="http:// ...
- nodejs调试
1.通过debug命令进行调试 node debug app.js 运行的结果: 在debug状态下输入"repl"命令可以评估变量和表达式的值 按下'CTRL+C'可以退出rep ...
- 关闭Centos的自动更新
昨天跟老板汇报,提到我们的linux服务器每天自动更新,老板大发雷霆,说生产系统不能够这样,非常不安全,一个师兄也提到他原来在移动的时候,服务器更新也是很谨慎的事情.看来我的思维太技术了,不够全面,所 ...
- python之socket编程
本章内容 1.socket 2.IO多路复用 3.socketserver Socket socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用[打开][读写][ ...
- 51单片机C语言学习笔记4:keil C51绝对地址访问
在利用keil进行8051单片机编程的时,常常需要进行绝对地址进行访问.特别是对硬件操作,如DA AD 采样 ,LCD 液晶操作,打印操作.等等.C51提供了三种访问绝对地址的方法: 1. 绝对宏: ...
- COJ 0026 汉诺塔问题
汉诺塔问题 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 经典的汉诺塔游戏相信很多同学都会玩的,规则就不用赘述,百科一下就OK ...
- sigaction函数的使用
sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作). 他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该 ...
- Java---设计模块(设计模块的简介及最简单的俩个单例代码加测试)
设计模式学习概述: ★ 为什么要学习设计模式 1.设计模式都是一些相对优秀的解决方案,很多问题都是典型的.有代表性的问题,学习设计模式,我们就不用自己从头来解决这些问题,相当于在巨人的肩膀上,复用这些 ...
- MongoDB开发学习(1)开天辟地,经典入门
原文地址:http://www.cnblogs.com/xumingxiang/archive/2012/04/08/2437468.html 如果你从来没有接触MongoDB或对MongoDB有一点 ...
- 关于Python中的for循环控制语句
#第一个:求 50 - 100 之间的质数 import mathfor i in range(50, 100 + 1): for j in range(2, int(math.sqrt(i)) ...