Crack密码验证小实验
首先来看一段用于密码验证的C语言代码:
#include<stdio.h>
#include<string.h>#define PASSWORD "1234567"int verify_password(char *password)
{int authenticated;authenticated = strcmp(password,PASSWORD);return authenticated;
}int 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;}}return 0;
}
由代码逻辑可知,必须输入正确的密码“1234567”才能得到密码验证的确认,跳出循环。不难发现,程序是提示密码错误请求再次输入,还是提示密码正确跳出循环,完全取决于main函数中的if判断。
如果我们能在.exe文件中找到if判断对应的二进制机器代码,将其稍作修改,那么即使输入错误的密码,也能通过验证,下面,将一步步来实现该软件的“爆破”。
实验环境:
操作系统:WinXP Sp3
编译器:Visual C++ 6.0
编译选项:默认编译选项
build版本:release版本
1.首先打开IDA,并把由VC 6.0得到的.exe文件直接拖进IDA,稍等片刻,反汇编工作将完成。反汇编流程图如下所示:
2.在IDA图形显示界面,用鼠标选中程序分支点,即要寻找的对应C代码分支点的if分支点,按空格键切换到汇编指令界面:
光标仍然显示高亮的这条汇编指令就是刚才在流程图中看到的分支指令。可以看到这条指令位于PE文件的.text节,并且IDA已经自动将该指令的地址换算成了运行时的内存地址VA:004010D5。
3.现在关闭IDA,换成OllyDbg进行动态调试来看看程序到底怎样分支的。用OllyDbg把PE文件打开,如下:
OllyDbg在默认情况下将程序中断在PE装载处开始,而不是main函数的开始。一般情况下,main函数位于GetCommonLineA函数调用后不远处,并且有明显的特征:在调用之前有3次明显的压栈操作,因为系统要给main传入默认的argc、argv等参数。找到main函数后,按F7键单步跟入就可以看到真正的代码了。
4.也可以按快捷键Ctrl+G直接跳到由IDA得到的VA:0x004010D5处查看那条引起程序分支的关键指令:
5.选中这条指令,按F2键下断点,成功后,指令的地址会被标记成不同颜色。
按F9键让程序运行起来,这时候程序控制权会回到程序,OllyDbg暂时挂起。到程序提示输入密码的Console界面随便输入一个错误的密码,回车确认后,OllyDbg会重新中断程序,收回控制权。
密码验证函数的返回值将存在EAX寄存器中,if()语句通过下列两条指令实现:
TEST EAX,EAX
JE XXXXX
也就是说,EAX中的值为0时,跳转将被执行,程序进入密码确认流程;否则跳转不执行,程序进入密码重输的流程。如果我们把JE这条指令修改为JNE(非0则跳转),那么整个程序的逻辑就会反过来:输入错误的密码被确认,输入正确的密码反而要求重新输入!
6.双击JE这条指令,将其修改成JNE,单击“Assemble”按钮将其写入内存,如下所示:
OllyDbg将汇编指令翻译成机器代码写入内存。原来内存中的机器代码74(JE)现在变成了75(JNE)。
7.上面只是在内存中修改程序,还需要在二进制文件中也修改相应的字节,需要用到内存地址VA与文件地址之间的对应关系。利用PEiD或类似软件打开.exe文件,查看PE文件的节信息:
我们已经知道跳转指令在内存中的地址是VA = 0x004010D5,按照VA与文件地址的换算公式:
文件偏移地址 = 虚拟内存地址(VA) - 装载基址(Image Base) - 节偏移 = 0x004010D5 - 0x00400000 - (0x00001000 - 0x00001000) = 0x10D5
也就是说,这条指令在PE文件中距离文件开始处10D5字节的地方。用UltraEdit按照二进制方式打开.exe文件,按Ctrl+G,输入0x10D5直接跳到JE指令的机器代码处,将这一字节的74(JE)修改成75(JNE),保存后重新运行可执行文件。
运行结果如下所示,原本正确的密码“1234567”现在反而提示错误了,而输入其他密码均能正确通过。
本实验出自王清的《0day安全:软件漏洞分析技术》第一章入门内容。
Crack密码验证小实验相关推荐
- Linux小实验——设备挂载、磁盘分区、格式化、RAID的配置、LVM配置、磁盘配额的配置方法和验证
小实验--设备挂载.磁盘分区.格式化.RAID的配置.LVM配置.磁盘配额的配置方法和验证 一.实验目的 二.要求 三.实验开始 1.加入新磁盘,创建分区,并把分区类型改成'8e'的RAID 2.创建 ...
- 小程序个人信息提交前关于姓名、手机号、车牌号、密码验证
为了防止用户提交空表单信息及在input框中填写不符合规则的信息,需要我们前端提前处理一下信息验证是否合理 在这里插入代码片 //验证输入框姓名不能为空 var realName = this.dat ...
- Shell编程之循环语句与常用转义字符及一些小实验
for循环语句 循环控制语句 seq命令 实例: while循环 实例: until循环 实例: 常用转义字符 shell脚本多重循环小实验 一.99乘法表 二.矩形 三.直角三角形 四.等腰直角三角 ...
- CMS垃圾收集器小实验之CMSInitiatingOccupancyFraction参数
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 背景 测试CMSInitiatingOccupancyFracti ...
- 用计算机做科学实验评课,科学小实验课程听课心得
010在线为您甄选多篇描写科学小实验课程听课心得,科学小实验课程听课心得精选,科学小实验课程听课心得大全,有议论,叙事 ,想象等形式.文章字数有400字.600字.800字....缓存时间: 2021 ...
- 华为动态NAT小实验演示
实验名称:华为动态NAT小实验演示 实验拓扑: 实验需求: R3为内网路由器做nat转换,R4为公网服务器,PC3 .PC4可以ping通PC5,但是PC5不能ping通PC3.PC4. 实验思路: ...
- linux php运行用户名和密码,Linux实例(一)使用用户名密码验证连接Linux
本篇文章给大家带来的内容是关于使用用户名密码验证连接Linux,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 如果您使用的是 SSH 密钥对,请参考 使用SSH密钥对连接Linux实 ...
- java正则表达式验证密码_最新密码验证正则表达式
正则表达式验证密码功能在项目中经常被使用到,但是很多朋友还是不大会使用密码正则表达式进行验证,本文小编为大家整理了php密码验证正则表达式.python密码强度正则,当然还有大家常用到的js正则表达式 ...
- oracle 11g 延迟验证,取消 11G延迟密码验证
新特性在提供方便,安全的同时,也会带来相应的bug. 11G引入了延迟密码验证,在输入错误的密码后,后续如果还是采用错误的密码登陆,将会导致密码延迟验证, 而且会导致失败登陆延长. 我们通过一个小例子 ...
最新文章
- ImageNet决定给人脸打码,却让哈士奇图片识别率猛增
- linux安装apache的纠结过程
- 3.Lasso线性模型
- USB数据线内阻对充电电流的影响
- C++对中文字符的处理
- java原始类型和引用类型_Java中的8种原始类型
- Golang 词法分析器浅析
- 《高质量程序设计指南》读书笔记
- 施耐德PLC Unity Pro xl 软件使用一
- cad计算机画图标准,CAD画图某些常用尺寸及作图习惯
- 常用数组方法汇总(ES3、ES5、ES6、ES7、ES10)
- google注册账号使用手机号提示注册此号码无法用于验证
- 前端面试题《CSS》
- visual svn for visual studio 2019
- 【20220207】【信号处理】三次样条插值原理详解
- 职教云助手手机版_职教云app下载安装_职教云最新版本下载网址
- 基于SLAM的机器人导航避障方案
- libjpeg与turbo libjpeg的使用
- 毕业论文图片、公式自动编号和交叉索引教程
- 新手小白如何短时间内熟练运营微信公众号