首页
论坛
专栏
课程

[原创]看雪CTF.TSRC 2018 团队赛-第六题 追凶者也--拼图游戏

2018-12-11 19:44 602

[原创]看雪CTF.TSRC 2018 团队赛-第六题 追凶者也--拼图游戏

2018-12-11 19:44
602

1.思路

       先看下前面大佬答题的时间,

有点变态的,不到一个小时就弄完了!说明可能有点希望 0.0 !!!!!

2.正文

刚开始那道题目的时候!
先运行下看下情况!
发现是个窗体程序
直接拖到IDA里面!

找到GetDlgItemTextA


然后由它的找到单击事件


咋一看,懵了!怎么没有判断序列号成功的地方!
刚开始怀疑类似于第二题,初始化一个全局或者静态的类对象,将验证算法藏在析构函数里面!奈何太菜没有找到!
然后又怀疑是不是栈溢出,但是输入的时候给定了最大长度!而且string的缓冲区也符合最大。
然后一点点想法,一点点否定。
最后将程序拖入study_pe的时候 ,

发现这么一个东西。。。TLS表!
这东西注册回调函数的时候,一般先于入口点运行!
算了一下偏移值!
base+0x122FC
因为程序有重定向
所以在IDA中我把base值设成0x1340000(实际情况,由你来定)
0x1340000 +0x122FC=0x13522FC

由它找到回调函数
一路跟下来找到主要调用的地方,

实际上每次调用GetDlgItemTextA之后,紧接着就会 调用这个函数(ps:藏的可真深啊!)
实际情况这样

看着很难看!
简单的定义了一个结构,让结果好看点

这里有一些地方没定义就是,是为了让ida识别的好看点,没有什么lowbyte的恶心人(ps:可能我是强迫症吧,嘻嘻)

从上图中逻辑中可以看出主要有两个检测点!
check1
check2
实际情况中,我过了一个答案就出来了!

初始化一个3x3的表。
4 1 3
7 2 5
8 6 0


因为结果需返回1,所以可知最后的表结构
1 2 3
4 5 6
7 8 0
不用想也知道上图中move,改变了表。
而且对传入的序列号进行了判断输入w -> 0 , d -> 1 , s -> 2 a -> 3
 经常 玩游戏的可能一下就反应过来了,这是方向键!
可能我太菜了,一下没有反应过来,哈哈!
进去move看一看。

看着很乱,但是用心分析很快也能分析出来
这是我粗略整理了一下
char __cdecl move(int s1, int s2)
{
	if(!s2)
		return 0;
	int j=0,i=0;
	for(j=0;j<3;j++){
		for(i=0;i<3;i++){
			if(table[j][i]==s2){
				switch ( s1 )
				{
				case 0:
					if ( j )
					{
						if ( table1[j - 1][i] )
						{
							result = 0;
						}
						else
						{
							table1[j - 1][i] = table1[j][i];
							table1[j][i] = 0;
							result = 1;
						}
					}
					else
					{
						result = 0;
					}
					return result;
				case 1:
					if ( i == 2 )
					{
						result = 0;
					}
					else if ( table1[j][i+1] )
					{
						result = 0;
					}
					else
					{
						table1[j][i+1] = table1[j][i];
						table1[j][i] = 0;
						result = 1;
					}
					return result;
					//break;
				case 2:
					if ( j == 2 )
					{
						result = 0;
					}
					else if ( table1[j + 1][i] )
					{
						result = 0;
					}
					else
					{
						table1[j + 1][i] = table1[j][i];
						table1[j][i] = 0;
						result = 1;
					}
					return result;
				case 3:
					if ( i )
					{
						if ( table1[j][i-1] )
						{
							result = 0;
						}
						else
						{
							table1[j][i-1] = table1[j][i];
							table1[j][i] = 0;
							result = 1;
						}
					}
					else
					{
						result = 0;
					}
					return result;
				default:
					;
				}
			}
		}
		
	}
}	
由此可以看出!对传入的参数在0 1 2 3中进行了判断,有w a s d 我们就就可以初步的推断是对表中的元素进行了移动。
结果正是如此,由上面化简的代码可知,实际上移动后的位置会被置为0,而后面判断的元素,每个都是初始化的内容!
所以可知移动的地方只能为0。
最后的表结构为
1 2 3
4 5 6
7 8 0
因此我们就可以大胆的猜测这是一个拼图游戏。
4 1 3          1 2 3
7 2 5   -- ->  4 5 6
8 6 0          7 8 0
下面就是写算法求解了
可能我太菜了,于是乎上网随便搜了一个。。。。。。。。。。。

3.结果


6 d
8 d
7 s
4 s
1 a
2 w
5 a
6 w
最后的序列号就为:d6d8s7s4a1w2a5w6

4.总结

       前面的大佬太强了,估计一下就看出算法了,还是经验太少!还需学习啊,幸好有看雪这么好的论坛在(舔狗,哈哈 ^.^),看雪万岁!!
有空自己实现下拼图算法再发出来!先发网上的....... 


[招聘]欢迎市场人员加入看雪学院团队!

最后于 2019-1-18 12:55 被大帅锅编辑 ,原因:
上传的附件:
最新回复 (0)
游客
登录 | 注册 方可回帖
返回