攻防世界 REVERSE 新手区/no-strings-attached

攻防世界 REVERSE 新手区/no-strings-attached

在这里插入图片描述

下载附件,用exeinfope查看一下信息

在这里插入图片描述

这个文件没有加壳,用IDA32bit打开,找到main函数,按f5查看伪代码

在这里插入图片描述

可以看到一共调用了四个函数,前三个函数没有有用的信息,所以重点看第四个函数

在这里插入图片描述

跟进查看第四个函数

在这里插入图片描述

分析代码:fgetws是从键盘读入一串字符,看到里面有 wcslen() 函数以及 wcscmp() 函数

在这里插入图片描述

可以看出这是一个字符串比较的算法,所以wcslen() = strlen()wcscmp() = strcmp()
用读入的字符串储存在 ws中,再与 s2比较,如果相等就输出success

那么接下来就是算出s2的值了

在这里插入图片描述

跟进s,每个14h的上一个16进制数就是s中的值,接下来一个一个把s的字符记下来

在这里插入图片描述

int s[] = {0x36,0x37,0x3B,0x80,0x7A,0x71,0x78,0x63,0x66,0x73,0x67,0x62,
               0x65,0x73,0x60,0x6B,0x71,0x78,0x6A,0x73,0x70,0x64,0x78,
                0x6E,0x70,0x70,0x64,0x70,0x64,0x6E,0x7B,0x76,0x78,0x6A,0x73,0x7B,0x80};

再看dword_8048A90,一样把它记下来

在这里插入图片描述

int dw[] = {2,3,4,5};

接下来跟进decrypt函数

在这里插入图片描述
在这里插入图片描述

一个很简单的算法,返回的是一个指针dest,那么dest就是flag了,照着写一遍就行

     int v6 = 37;
     int v7 = 4;
     int v4 = 0;
     while( v4 < v6)
     {
         for(int i = 0; i < v7 && v4 < v6 ; i++)
         {
             s[v4 ++] -= dw[i];
         }
     }

完整代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
	int dw[] = {2,3,4,5};
	int s[] = {0x36,0x37,0x3B,0x80,0x7A,0x71,0x78,0x63,0x66,0x73,0x67,0x62,
               0x65,0x73,0x60,0x6B,0x71,0x78,0x6A,0x73,0x70,0x64,0x78,
                0x6E,0x70,0x70,0x64,0x70,0x64,0x6E,0x7B,0x76,0x78,0x6A,0x73,0x7B,0x80};
     int v6 = 37;
     int v7 = 4;
     int v4 = 0;
     while( v4 < v6)
     {
         for(int i = 0; i < v7 && v4 < v6 ; i++)
         {
             s[v4 ++] -= dw[i];
             printf("%c",s[v4 - 1]);
         }
     }
	return 0;
}

运行结果

在这里插入图片描述

这结果一看就不对,,,,, ,可以看到这个结果的开头有个447,再看下题目,题目来源来自于9447 CTF ,对上了3个数字,但是少了一个9

在这里插入图片描述

根据之前那个加密的算法,推测出s和dw都少了前面的一位数

   int v6 = 37;
     int v7 = 4;
     int v4 = 0;
     while( v4 < v6)
     {
         for(int i = 0; i < v7 && v4 < v6 ; i++)
         {
             s[v4 ++] -= dw[i];
         }
     }

再看下s和dw,在开头都有个dd ,后面的数都只有两位数,而这个有四位数,所以143Ah取后半个部分得到14h,dw同理,得到 01

在这里插入图片描述
在这里插入图片描述

将这两个缺的数字加到开头

int dw[] = {1,2,3,4,5};
	int s[] = {0x3A,0x36,0x37,0x3B,0x80,0x7A,0x71,0x78,0x63,0x66,0x73,0x67,0x62,
               0x65,0x73,0x60,0x6B,0x71,0x78,0x6A,0x73,0x70,0x64,0x78,
                0x6E,0x70,0x70,0x64,0x70,0x64,0x6E,0x7B,0x76,0x78,0x6A,0x73,0x7B,0x80};

下面是完整代码

#include <stdlib.h>
#include <stdio.h>
int main()
{
	int dw[] = {1,2,3,4,5};
	int s[] = {0x3A,0x36,0x37,0x3B,0x80,0x7A,0x71,0x78,0x63,0x66,0x73,0x67,0x62,
               0x65,0x73,0x60,0x6B,0x71,0x78,0x6A,0x73,0x70,0x64,0x78,
                0x6E,0x70,0x70,0x64,0x70,0x64,0x6E,0x7B,0x76,0x78,0x6A,0x73,0x7B,0x80};
     int v6 = 38;
     int v7 = 5;
     int v4 = 0;
     while( v4 < v6)
     {
         for(int i = 0; i < v7 && v4 < v6 ; i++)
         {
             s[v4 ++] -= dw[i];
             printf("%c",s[v4 - 1]);
         }
     }
	return 0;
}

运行得到flag:9447{you_are_an_international_mystery}

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ofo300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值