本次免考实践方向是0day漏洞,以博客的形式记录了我的学习实践过程。第一篇博客主要围绕什么是0day漏洞以及一些以后学习中需要的基础知识和必备工具进行简单介绍和具体的操作。
我们通常把一些引起系统软件做“超出设计范围内的事情”的bug称作是漏洞,实际上漏洞和bug也是有一些区别的。
它是危害最大的漏洞,对攻击者来说也是最有价值的漏洞。如果被曝光,那么在广商的官方补丁发布之前,整个网络都处于高危预警状态。
PE是win32平台下可执行文件遵守的数据格式。常见的格式有exe文件、dll文件等。
PE文件格式把可执行文件分为若干个数据节(section),不同的资源放在不同的节中,一个典型的PE文件包含的节如下:
* .text:由编译器产生,存放着二进制的机器代码,反汇编和调试的对象。
* .data:初始化的数据块,如宏定义、全局变量、静态变量等
* .idata:可执行文件所使用的动态链接库等外来函数与文件的信息。
* .rsrc:存放程序的资源,如图标、菜单等。
* 除此之外,还可能出现“.rdata",".tls"等。
windows的内存被分为了两个层面。通常在用户模式下,我们用调试器看到的内存都是虚拟内存。
* 物理内存:需要进入内核级别ring0才能看到。
* 虚拟内存:在用户态ring3下,就可以通过调试器来看到内存地址。
如下图所示,是windows虚拟内存和物理内存的示意图。windows让所有进程都相信自己拥有独立都有4GB的内存空间【这些空间包含了程序运行所必需的资源,如代码、栈空间、堆空间等】,都是可以访问的,但实际上运行时能用到的空间根本没有这么多。只有需要进行实际的内存操作的时候,内存管理器才会将“虚拟地址”和“物理地址”相联系起来。
首先,要理解几个概念,我们才可以弄清楚PE文件地址和虚拟内存地址之间的映射关系。
装载基址(Image Base):PE装入内存时的基地址。
* EXE文件在内存中的基地址是0x00400000
* DLL文件在内存中的基地址是0x10000000
* 基地址是可以通过修改编译选项来更改
相对虚拟地址(Relative Virtual Address,RVA):内存地址相对于映射基址的偏移量。.
PE文件按照两种数据标准存放:
所以当把文件便宜到虚拟内存地址的换算时,还要看所转换的地址位于第几个节内,这种由存储单位引起的节基址差叫做节偏移。
.text节偏移=0x1000-0x400=0xc00
.rdata节偏移=0x7000-0x6200=0xE00
.data节偏移=0x9000-0x7400=0x1C00
OllyDbg是一个集成了反汇编分析、十六进制编辑、动态调试等多种功能于一身的功能强大的调试器。
主界面共有五个窗口:
主要的快捷键:
IDA Pro是一款反汇编的软件,在大多数情况下用于静态反汇编。
它可以对代码单元进行标注。使用IDA对函数进行标注和注解可以做到全文交叉调用,能够自动识别出系统调用。并且,目前的IDA可以用图形的方式显示出一个函数内部的执行流程,在反汇编界面中按空格键进行汇编代码和图形显示两种模式的切换。
Ultra Edit是IDM Computer Solutions公司出品的著名文本编辑器。 这款功能强大的文本编辑器,可以编辑文字、Hex、ASCII码,可以取代记事本,内建英文单字检查、C++ 、Java、HTML、VB等多种语言的指令突显,可同时编辑多个文件,而且即使开启很大的文件速度也不会慢。
Lord PE是一款强大的可执行文件分析辅助脱壳工具,附带16进制编辑器.不包括反汇编模块。字啊本次学习中,我们用它来查找虚拟内存地址和文件偏移地址来进行地址转换。
本实验的目的是通过应用刚才介绍的工具来破解程序的密码。
首先我们看一下源码:
#include <stdio.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
int authenticated;
authenticated=strcmp(password,PASSWORD);
return authenticated;
}
main()
{
int valid_flag=0;
char password[1024];
while(1)
{
printf("please input password: ");
scanf("%s",password);
valid_flag = verify_password(password);
if(valid_flag)
{
printf("incorrect password!\n\n");
}
else
{
printf("Congratulation! You have passed the verification!\n");
break;
}
}
}
功能是一个密码的验证。我们必须输入正确的密码“1234567”时,才能得以确定成功,跳出循环,否则会一直提示密码错误请求再次输入。
step1:用IDA,查找跳转指令的内存地址
从流程图可以清晰地看到,if语句的分支语句为"jz short"。
按下空格键切换到汇编指令界面,即可找到该语句所在的内存地址,即在.text节0x004010D5,如下图所示:
step2:用ollydbg,在内存中修改程序
此时,可以看到原来内存中的机器码从74也变到了75。
step3:用LordPE,查看PE节信息
用LordPE打开.exe文件,查看文件节信息
step4:用Ultra,修改.exe文件的十六进制代码
回顾整个实验,其实我们就是将整个程序的逻辑反了过来。将机器代码修改从JE修改为JNE,把逻辑变成非0则进行跳转。因此,输入正确密码判断为0,当然会提示密码错误啦!
原文:https://www.cnblogs.com/0831j/p/9218343.html