[原创]ctf2017_Fpc分析
题目刚拿下来,按照正常思路进行反编译,根据关键字找到主函数:

F5初步分析sub_401050,sub_401090,sub_4010E0三个函数的功能:
1. sub_401050 提示并获取用户输入,有调用scanf,输入的有效长度为8个字节;
2. sub_401090,
sub_4010E0 对验证码的两次验证过程,关键有两个验证公式,
其中v1和v0分别是输入字符串的高4位和低4位
:


分析方法一:
按照两个函数的验证方法来尝试反推v0和v1,由于方程组如果不考虑溢出肯定是无解的,而在考虑溢出的情况下,对高位做补位后单独计算 sub_401090或者 sub_4010E0 中的函数组是有解的,但两组解不相等,纠结了半天后,重新考虑是不是无解的,题目的本意不是计算验证码。所以对方程组重新做了分析。
假设v0, v1都是偶数,v1-v0则为偶数,那么sub_4010E0中17*(v1-v0)+v1一定是偶数;
假设v0, v1都是奇数,v1-v0则为偶数,那么sub_401090中5*(v1-v0)+v1一定是 奇数;
假设v0为奇数,v1都是偶数,v1-v0则为奇数,那么 sub_401090中5*(v1-v0)+v1一定是 奇数;
假设v0为偶数,v1都是奇数,v1-v0则为奇数, 那么sub_4010E0中17*(v1-v0)+v1一定是偶数 ;
四种假设都让函数中的部分公式结果的奇偶性冲突,所以正常解出验证码应该是不可能吧。
分析方法二:
上面提到,程序调用scanf,并默认输入验证码的长度为8,可以利用溢出改写函数的跳转实现破解。
ida开启动态调试,我们的目的是跳转到地址0x40102f
[图片:627010_omrulfzp18j7g1n.png]
在函数 sub_401050打上断点,运行F7进入函数,在随意输入验证码12345678后观察ESP中的变化:

0x0040101C是第一个验证函数 sub_401090 的地址,可以尝试把该地址改成0x0040102f直接跳转到验证成功,
linux或cygwin环境下执行echo 3132333435363738393031322f104000 | xxd -r -ps > code
或者用二进制编辑器,前12个字节可以随机,后四个字节保证是 2f104000即可,然后控制台输入

但这种方法应该不是作者的思路吧,因为无法正常输入这些字节到程序中,结果无法提交,毕竟小白一枚,能想到的有限,结束后再看看其他大牛的解决思路。
