好友
阅读权限30
听众
最后登录1970-1-1
|
本帖最后由 whklhh 于 2017-10-17 11:31 编辑
Reversing.kr是韩国的一个逆向题目网站
有分国度的排行榜,还是挺有意思的
本题即来自于第十九关x64 Lotto
http://reversing.kr/challenge.php可以下载到文件
从名字中就可以看出来这是一个x64程序
ExeInfoPe和PEiD似乎都不太支持x64的查壳的样子
试运行,是一个CUI程序,提示Input the number
输入了几个数字似乎都没反应
直接拖入64位IDA中,还好没壳,可以直接反编译
流程比较清晰,先scanf_s接收6个整数,这也是我之前输入没反应的原因
然后清屏
与时间作为种子的六个随机数比较,全部错误的话就回头重新提示Input the number
不过有个地方挺奇怪的,程序本身以v6作为正确字符计数器,却还用v5作为错误flag,不知道是多此一举还是故意挖坑……
再往后是flag生成代码,通过硬编码进行运算
最简单的方法
#####动态调试
虽然x64不能使用OD,但是还有其他调试器可以使用,比如说IDA
IDA使用remote windows debugger就可以了(虽然不知道为什么明明就在本地还要远程连接)
打开dbgsrv文件夹下的win64_remotex64.exe,提示ip和port,在IDA的debugger中设置完成后就可以了
断下来以后直接粗暴的跳到flag生成处,注意不要被v5坑了就好
注意wprintf后再断住看flag的值(我刚开始兴奋地F9以后程序直接结束了OTZ)
次一点的方法
#####针对rand()的伪随机数进行攻击
由于time64的单位是秒,因此我们可以写一个程序同样调用time函数得到秒数作为种子
生成6个数字作为输入送给lotto程序rand是伪随机数,种子相同时随机数列也相同,而运行时间只要在同一秒内,种子就是相同的
C脚本:
[C++] 纯文本查看 复制代码 #include <stdio.h>[/size]
#include <stdlib.h>
#include <time.h>
void main()
{
char s[100];
int n[6], i;
time_t t;
t = _time64(NULL);#得到当前时间秒数
srand(t);#随机数生成种子
for(i=0;i<6;i++)
n[i] = rand()%100;#取出数列中的6个数
sprintf(s, "echo %d %d %d %d %d %d | F:\\ctf\\reversing.kr\\Lotto\\Lotto.exe", n[0], n[1], n[2], n[3], n[4], n[5]);#生成通过管道送入值的字符串
system(s);#控制台调用
system("pause");
}
最差也是最直接的方法
#####研究flag生成的算法
程序中有两个硬编码,先将他们一一对应异或,然后再异或0xF并加下标
生成起来不怎么难
Python脚本:
[Python] 纯文本查看 复制代码 n = [184, 92, 139, 107, 66, 184, 56, 237, 219, 91, 129, 41, 160, 126, 80, 140, 27, 134, 245, 2, 85, 33, 12, 14, 242]
d = [231, 51, -11, 20, 62, 221, 91, 191, 204, 52, 231, 51, -11, 20, 62, 221, 91, 191, 204, 52, 68, 100, 20, 73, -12]
for i in range(len(d)):
if(d<=0):
d = d + 256
for i in range(len(n)):
print(chr((n ^ d ^ 0xF) + i), end='')
这个程序很简单,不过解题思路有多种,还是挺有意思的
不像那种掷骰子要求出7的铁了心要爆破的题目……
|
免费评分
-
查看全部评分
|