171014 逆向-Reversing.kr(x64 Lotto)

来源:互联网 发布:海康威视端口未生效 编辑:程序博客网 时间:2024/06/05 15:50

1625-5 王子昂 总结《2017年10月14日》 【连续第379天总结】
A. reversing.kr
B.

x64 Lotto

从名字中就可以看出来这是一个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脚本:

#include <stdio.h>#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脚本:

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[i]<=0):        d[i] = d[i] + 256for i in range(len(n)):    print(chr((n[i] ^ d[i] ^ 0xF) + i), end='')

这个程序很简单,不过解题思路有多种,还是挺有意思的
不像那种掷骰子要求出7的铁了心要爆破的题目……

C. 明日计划
DLL注入理论知识

原创粉丝点击