GACTF2020 - Wannaflag wp

GACTF2020 - Wannaflag

题目链接
十分传统的一个winapi逆向。最近也很少见了,对新人有难度但有趣。
本篇的一些细节之处省略截图,但我会把步骤写明白。若复现不出来可评论或私信。

程序拿到手还有点大,443kb
同时附带了一个flag.bin 进去,打开发现是可读的一串字符串。很显然是被加密过了。

查pe,32位无壳 vs编译(这里我用的exeinfo)

ida一打开就定位到了WinMain。这里很容易看出来其只调用了两个自定义函数 – 背景音乐(1b20),消息处理(2280)
进消息处理函数(函数偏移2280)检查在这里插入图片描述
首先开头两个case是没什么营养的,重点放在东西很多的case 5
在这里插入图片描述

首先这里通过GetWindowsTextA获取了我们的输入串,还去了一个长度。然后厦门进行了一连串的不可名状的变换。不过这里取的元素十分清晰。我们先看一下这个Paint结构体的定义
在这里插入图片描述
在这里插入图片描述
额,简单的说就是查不到啥。不过如果这些东西要作为解题步骤的一部分的话,极有可能是固定值。先看看后面
在这里插入图片描述
首先MessageBox(orz)哪里应该就是我们的正确跳转。因为底下调用的偏移1f20处调用了flag.bin,解密并创建了flag.txt文件夹。但是这里的解密流程十分混沌,至少我静态解不出来。不过外部的流程很清晰。因此这里应该就是两种解法:动调直接调用1f20,或者静态解密解出key。我估摸着动调不太能直接解,因为Paint结构体包含了我们输入的字符串。

而简单分析一下程序流程:先将v57数组和byte42ae0进行异或并左移一位(注意是循环左移),而后这个数组要与底下的这个78d8进行比较,是不是很简单呢?

但是问题来力,这个v57是什么?

经过简单的调用分析和推理(猜)可知,这里应该是我们的输入串。不过上方又有一个看起来非常痛苦的操作,其满足条件是输入串长度大于等于0x40。

但是这里,我们或者通过字符串长度推理,或者通过动调都可以发现 – 这个条件是满足不了的。因此我们只需要对这个变换和check进行逆向就好啦。

exp:

#include<stdio.h>
#include<string.h>
#include<windows.h> 
#include<string.h>
#include<tchar.h>
//#+OXJ xnB1 QWT4 9cnW cGFB ZOjn yfZo ZV1m 7+/v /29t f2c= 

int ror(unsigned int a,unsigned int b)
{
    unsigned char c = a,d = 0;
    for(int i = 0; i < b; i++)
    {
    	c=(c>>1)|(c<<7);
	}
    return c;
 } 

int main()
{
//	printf("%x\n",0xae>>1);
    unsigned char key[0x1f]  = {0x4e,0xae,0x61,0xba,0xe4,0x2b,0x55,0xaa,0x59,0xfc,0x4d,0x2,0x17,0x6b,0x13,0xa1,0x41,0xfe,0x35,0xb,0xb4,0xb,0x52,0x2f,0x46,0xcc,0x35,0x82,0xe5,0x88,0x50};
    unsigned char ca[] = "ANNAWGALFYBKVIAHMXTFCAACLAAAAYK";
    unsigned char v38[] = {1,2,6,24,120,720,5760};
	for(unsigned int i = 0; i <= 0x1e; i++)
	{
		printf("%x ",ror(key[i],i));
		key[i] = (ror(key[i],i))^ca[i];
		//printf("%d ",key[i]);
	}
	printf("\n");
	for(int l = 0; l < 7; l++)
	{
		for(int i = 0; i <= 0x1e; i++)
     	{
		printf("%c",key[i]^v38[4]);
	    }
	    printf("\n");
	}


}
 

再一跑,欸嘿,flag。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值