0day 安全学习笔记01-小实验
0day 安全学习笔记01-小实验
日期:Feb-23-2022
作者:狐狸大剑眼镜<-----这是一个菜鸡( $ _ $ )
书籍:0day 安全:软件漏洞分析技术
参考:https://zhuanlan.zhihu.com/p/354400717 # vscode配置c
https://www.cnblogs.com/itheidou/p/15101734.html
https://www.cnblogs.com/blacksunny/p/7203268.html
https://www.cnblogs.com/ichunqiu/p/11763589.html
https://zhuanlan.zhihu.com/p/82177268 #IDA pro新手入门
http://ollydbg.com/ ollydbgx64 ,https://www.52pojie.cn/thread-1087591-1-1.html
https://pan.baidu.com/s/1nUOVl2pIvhf7bf-U2VrNaw提取码: a6cr
https://www.chinapyg.com/thread-137051-1-1.html
chrome ctrl+shift+t关闭刚关闭的页面
环境配置
自己的vscode只配置了python环境,需要再配置c环境
下载Mingw-w64编译器 https://www.mingw-w64.org/downloads/
扩展市场“的搜索框中输入”C/C++“,安装,然后安装“Code Runner”扩展
打开设置,找到扩展,把图中三个选项打勾
解压下载好的Mingw-w64,进入bin目录,添加path环境变量。
控制台输入gcc -v查看。这一看路径不太对啊,可能以前安装过。
创建一个文件夹用vscode打开,创建一个helo.c文件
还需要配置俩json文件。
首先,在”Terminal“菜单下点击”Configure Tasks...”子菜单。
在随后出现的弹出框中选择“C/C++:gcc.exe生成活动文件”,会自动生成一个“.vscode"的子文件夹,在这个子文件夹下自动创建一个”tasks.json“的文件。路径改为自己刚安装的编译器
然后就可以run
调试的话点击“Run”菜单下的“Start Debugging”子菜单。在随后出现的弹出框中选择“C++(GDB/LLDB)”,再选择”gcc.exe“。
一个小实验
('-')('-')
写一个密码比较。
#include <stdio.h>
#define PASSWORD "1234567"
int verify_password(char *password)
{
int yanzheng;
// 比较两个字符串
yanzheng = strcmp(password, PASSWORD);
return yanzheng;
}
int main()
{
int flag = 0;
char password[1024];
while(1)
{
printf("please input password\n");
scanf("%s", &password);
flag = verify_password(password);
if(flag == 0)
{
printf("password is ok");
break;
}
else{
printf("error");
}
}
}
打包成exe文件
控制台输入
gcc hello1.c -o hello
程序是提示密码错误请求再次输入,还是提示密码正确跳出循
环,完全取决于 main 函数中的 if 判断。如果我们能在.exe 文件中找到 if 判断对应的二进制机器代码,将其稍作修改,那么即使输错了也能通过验证。
将exe拖进ida
IDA View-A是反汇编窗口,
HexView-A是十六进制格式显示的窗口,
Imports是导入表(程序中调用到的外面的函数),
Functions是函数表(这个程序中的函数),
Structures是结构,
Enums是枚举
IDA打开应用程序时,会为其创建一个数据库,后缀为IDB。IDB由4个文件组成:
- 后缀为id0的二叉树形式的数据库,
- 后缀为id1的程序字节标识,
- 后缀为nam的Named窗口的索引信息,
- 后缀为til的给定数据库的本地类型定义的相关信息。
F5查看伪代码,还原个大概<( ̄︶ ̄),按F12,IDA 会自动绘制出更加专业和详细的函数流程图,但是我的报错Command "LuminaPullAllMds" failed,不知道是啥原因,百度一个词条都没有。
按空格键切换流程和汇编,可以右键graph view和text view
找到引起程序分支的那个指令鼠标选中按空格
可以看到这条指令位于 PE 文件的.text 节,并且 IDA 已经自动将该指令的地址换算成了运行时的内
存地址 VA:004015D8。
现在关闭 IDA,换用 OllyDbg 进行动态调试来看看程序到底是怎样分支的。用 OllyDbg 把
PE 文件打开.
按快捷键ctrl+g,直接追踪VA地址
选中这条指令,按 F2 键下断点,成功后,指令的地址会被标记成红色
按 F9 键让程序运行起来,这时候控制权会回到程序,OllyDbg 暂时挂起。到程序提示输入
密码的 Console 界面随便输入一个错误的密码,回车确认后,OllyDbg 会重新中断程序,收回
控制权
密码验证函数的返回值将存在 EAX 寄存器中,if()语句通过以下两条指令实现
TEST EAX,EAX
JE XXXXXEAX 中的值为 0 时,跳转将被执行,程序进入密码确认流程;否则跳转不执行,
程序进入密码重输的流程。由于现在输入的是错误密码,所以可以在预执行区看到提示:“Jump
is not taken”。
如果我们把 JE 这条指令的机器代码修改成 JNE(非 0 则跳转),那么整个程序的逻辑就会
反过来:输入错误的密码会被确认,输入正确的密码反而要求重新输入!当然,把
TEST EAX, EAX
指令修改成
XOR EAX, EAX也能达到改变程序流程的目的,这时不论正确与否,密码都将被接受。
双击 JE 这条指令,将其修改成 JNE,单击“Assemble”按钮将其写入内存OllyDbg 将汇编指令翻译成机器代码后写入内存。原来内存中的机器代码 74(JE)现在变
成了 75(JNE)。此外,在预执行区中的提示也发生了变化,提示跳转将要发生,也就是说,
在修改了一个字节的内存数据后,错误的密码也将跳入正确的执行流程!后面您可以单步执行,
看看程序是不是如我们所料执行了正确密码才应该执行的指令。
汇编语言中,JE表示等于就跳转,JNE是不等于就跳转。我发现我的是75啊,奥,我写的不太一样,我的是判断正确就跳转,否则循环,作者相反
#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;
}
}
}
修改为JE,改为正确跳转。单击“Assemble”按钮将其写入内存,运行,错误密码正确了
这就完成破解了嘛,不,这只是在内存中修改,从新运行还是和之前一样。
要从根源中破解要修改二进制文件。
关闭OllyDBG软件,打开LordPE,想着老的软件Win10可以用吗,在看雪上大佬说StudyPE好用。
飘云阁【五一礼物】:https://www.chinapyg.com/thread-137051-1-1.html
下载地址:
x86版:
链接: https://pan.baidu.com/s/1SidyyWbm7UQixeks5xkAAA 提取码: bxj5
x64版:
链接: https://pan.baidu.com/s/1HLwq1uyMUasTKqP2g7HT7Q 提取码: tuvw
FOa 和 **Rva **以及 Va 中转换,这个浮动窗口可以让你随时随地的转换这几个数据。 这个窗口可以随时从工具栏的按钮中打开或者关闭。
非常好用呀
VA 与文件地址的换算公式:
文件偏移地址 = 虚拟内存地址(VA)- 装载基址(Image Base)- 节偏移
= 0x0040106E-0x00400000-(0x00001000-0x00001000)
= 0x106E
RVA | 英文全称Relatively Virtual Address。偏移(又称“相对虚拟地址”)。相对镜像基址的偏移。 |
---|---|
节 | 节是PE文件中代码或数据的基本单元 |
VA | 虚拟地址,也就是程序被加载到内存中的地址 |
什么是偏移量?
汇编语言中的定义为:
把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为“有效地址或偏移量”。 亦: 存储单元的实际地址与其所在段的段地址之间的距离。本质其实就是“实际地址与其所在段的段地址之间的距离”
更通俗一点讲,内存中存储数据的方式是:一个存储数据的“实际地址”=段首地址+偏移量,
你也可以这样理解:就像我们现实中的“家庭地址”=“小区地址”+“门牌号”
上面的“偏移量”就好比“门牌号”
自带的工具很方便。
验证一下文件偏移地址=(虚拟地址VA) 004015D8 - (装载基址ImageBase)0x00400000
= 0x15D8
这条指令在 PE 文件中位于距离文件开始处 15D8 字节的地方
使用UltraEdit ,ctrl+g搜索0x15D8
怎么没找到我的75呢,算的还是有问题啊,哎嗨,不对啊0x15D8是RVA啊
对了,那个转换FOA是啥
我擦,它是文件偏移地址。
原来RVA是相对虚拟地址,可是上面那个计算结果怎么和RVA对上了呢,看一下作者是怎么算的
奇怪啊,是吧
好了,修改75为74
改完一闪而过没问题了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架