测试文件:https://lanzous.com/icfcxtg

代码分析

unsigned __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{_QWORD *v3; // ST08_8__int64 v5; // [rsp+10h] [rbp-30h]__int16 v6; // [rsp+18h] [rbp-28h]__int64 v7; // [rsp+20h] [rbp-20h]__int16 v8; // [rsp+28h] [rbp-18h]char v9; // [rsp+2Ah] [rbp-16h]unsigned __int64 v10; // [rsp+38h] [rbp-8h]v10 = __readfsqword(0x28u);v5 = 0LL;v6 = 0;v7 = 0LL;v8 = 0;v9 = 0;__isoc99_scanf("%s", &v5, a3);if ( (unsigned int)sub_4006D6((const char *)&v5) ){v3 = sub_400758((__int64)&v5, 0, 10);sub_400807((__int64)v3, (__int64)&v7);v9 = 0;sub_400881((char *)&v7);if ( (unsigned int)sub_400917() ){puts("your are cxk!!");}else{puts("TQL!");printf("flag{", &v7);printf("%s", &v5);puts("}");}}return __readfsqword(0x28u) ^ v10;
}

sub_4006D6函数很好理解,用来判断输入字符数组长度是否为10,且每个字符是否为'0'~'4'

这道题最简单的方法应该是,直接爆破就行,反正10位数,0~4444444444,直接就出结果了,另一种就是老老实实分析了。

二叉树遍历

接着sub_400807和sub_400881函数,实际就是一个二叉树的先序遍历和中序遍历,对字符数组中的下标进行排序。

先看看sub_400807,我们来构建出数组下标的二叉树

_QWORD *__fastcall sub_400758(__int64 a1, int a2, int a3)
{_QWORD *v4; // rax_QWORD *v5; // ST28_8int v6; // [rsp+0h] [rbp-30h]char v7; // [rsp+1Fh] [rbp-11h]v6 = a3;v7 = *(_BYTE *)(a2 + a1);if ( v7 == 0x20 || v7 == 0xA || a2 >= a3 )return 0LL;v4 = malloc(0x18uLL);v5 = v4;*(_BYTE *)v4 = v7;v4[1] = sub_400758(a1, 2 * a2 + 1, v6);v5[2] = sub_400758(a1, 2 * (a2 + 1), v6);return v5;
}

写成可执行的C语言程序,我们可以看到下标的先序遍历顺序(注意:大于等于10的值实际就是NULL,上面代码也可以看到return 0)

#include <iostream>using namespace std;void func1(int a2, int a3) {cout << a2 << endl;if (a2 >= a3)return;func1(2 * a2 + 1, a3);func1(2 * (a2 + 1), a3);
}int main()
{func1(0,10);system("PAUSE");return 0;
}

先序遍历的结果即为:0137849256,构建出二叉树

因此中序遍历的结果为:7,3,8,1,9,4,0,5,2,6

实际上还有一个更简单的方式,得到中序遍历结果。我们直接输入0~9,它的值即代表下标。修改sub_4006D6判断结果,跳过函数,最后在sub_400881中下断点,我们一样能够得到期望的结果。

sub_400881函数实际就是,一个按照中序遍历顺序给byte_601062按顺序赋值。(byte_601062是不完整的,我们主要是给'#'处赋值,你排列出来就可以看出是一个5x5的数独)

解数独

sub_400917函数

__int64 sub_400917()
{unsigned int v1; // [rsp+0h] [rbp-10h]signed int i; // [rsp+4h] [rbp-Ch]signed int j; // [rsp+8h] [rbp-8h]int k; // [rsp+Ch] [rbp-4h]v1 = 1;for ( i = 0; i <= 4; ++i ){for ( j = 0; j <= 4; ++j ){for ( k = j + 1; k <= 4; ++k ){if ( *((_BYTE *)&unk_601060 + 5 * i + j) == *((_BYTE *)&unk_601060 + 5 * i + k) )v1 = 0;if ( *((_BYTE *)&unk_601060 + 5 * j + i) == *((_BYTE *)&unk_601060 + 5 * k + i) )v1 = 0;}}}return v1;
}

这就是个检测横纵是否有相同元素的函数(数独的规则),我直接爆破出结果。

#include <iostream>
#include <Windows.h>using namespace std;#define N 52int func(int* s) {bool v1 = TRUE;for (int i = 0; i <= 4; ++i) {for (int j = 0; j <= 4; ++j) {for (int k = j + 1; k <= 4; ++k) {if (s[5 * i + j] == s[5 * i + k]) {v1 = FALSE;return v1;}if (s[5 * j + i] == s[5 * k + i]) {v1 = FALSE;return v1;}}}}return v1;
}int main()
{int s[] = { 0x31,0x34,0x23,0x32,0x33,0x33,0x30,0x23,0x31,0x23,0x30,0x23,0x32,0x33,0x23,0x23,0x33,0x23,0x23,0x30,0x34,0x32,0x23,0x23,0x31};for (int i = 48; i <= N; ++i) {for (int j = 48; j <= N; ++j) {for (int k = 48; k <= N; ++k) {for (int a = 48; a <= N; ++a) {for (int b = 48; b <= N; ++b) {for (int c = 48; c <= N; ++c) {for (int d = 48; d <= N; ++d) {for (int e = 48; e <= N; ++e) {for (int f = 48; f <= N; ++f) {for (int g = 48; g <= N; ++g) {s[2] = i;s[7] = j;s[9] = k;s[11] = a;s[14] = b;s[15] = c;s[17] = d;s[18] = e;s[22] = f;s[23] = g;if (func(s)) {cout << s[2] << " " << s[7] << " " << s[9] << " " <<s[11] << " " << s[14] << " " << s[15] << " " <<s[17] << " " << s[18] << " " << s[22] << " " << s[23];system("PAUSE");return 0;}}}}}}}}}}}system("PAUSE");return 0;
}

得到了byte_601062的值,我们又知道赋值给它的顺序,因此只需要反向根据下标赋值回去就行。

脚本

# -*- coding:utf-8 -*-model = [7, 3, 8, 1, 9, 4, 0, 5, 2, 6]
s = [48, 52, 50, 49, 52, 50, 49, 52, 51, 48]flag = [0] * 10for i in range(10):flag[model[i]] = s[i]
print ('flag{' + ''.join([chr(x) for x in flag]) + '}')

get flag!

flag{1134240024}

BUUCTF--[GUET-CTF2019]number_game相关推荐

  1. [*CTF2019]She buuctf

    [*CTF2019]She 下载附件,发现是玩游戏,分析一下文件发现是RPG Maker,我们下载一下RPG Maker XP V1.03 新建进程,吧Game.rxproj放到She下,然后再次打开 ...

  2. BUUCTF reverse题解汇总

    本文是BUUCTF平台reverse题解的汇总 题解均来自本人博客 目录 Page1 Page2 Page3 Page4 Page1 easyre reverse1 reverse2 内涵的软件 新年 ...

  3. BUUCTF的Web真题学习整理(一)

    目录 WEB1-WarmUp (任意文件包含漏洞) WEB2-高明的黑客(fuzz脚本) WEB3-easy_tornado (服务端模板注入(ssti攻击)) WEB4-Hack World(时间盲 ...

  4. BUUCTF寒假刷题-Web

    前言 寒假横向刷题(尽量) BUUCTF

  5. BUUCTF之[Zer0pts2020]Can you guess it? basename函数绕过

    BUUCTF之[Zer0pts2020]Can you guess it? basename函数绕过 题目 后台PHP源码: <?php include 'config.php'; // FLA ...

  6. BUUCTF刷题笔记

    BUUCTF刷题笔记 [极客大挑战 2019]BabySQL 从这句话我们可以看出,这个网站的后台是做了过滤处理的 这个时候我们先用万能密码实验一下看看,是什么类型的SQL注入 输入1',看看返回的结 ...

  7. BUUCTF Quoted-printable编码

    Quoted-printable可译为"可打印字符引用编码",编码常用在电子邮件中,如:Content-Transfer-Encoding: quoted-printable ,它 ...

  8. BUUCTF NewStarCTF一些新知识记录

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.eazyxor 二.RSA_begin 三.Yesec no drumsticks 四.EzSnake 五.Pyre ...

  9. buuctf Mark loves cat

    buuctf Mark loves cat 打开是个静态页面,源码也无任何有用信息 dirsearch扫描后发现.git泄露 GitHack.py下载得到两个php文件,接下来就是代码审计: flag ...

  10. BUUCTF·[MRCTF2020]天干地支+甲子·WP

    题目来源 BUUCTF在线评测 (buuoj.cn) 附件 得到得字符串用MRCTF{}包裹 一天Eki收到了一封来自Sndav的信,但是他有点迷希望您来解决一下 甲戌 甲寅 甲寅 癸卯 己酉 甲寅 ...

最新文章

  1. 文件目录表(FDT)及其结构
  2. “史上最全PyTorch资源汇总“(转载)
  3. 登录之图形跟短信验证码
  4. SAP实施的难点在哪里?
  5. CGGeometry基础
  6. mysql 查看集群状态_MySQL数据库集群正确配置步骤
  7. SAP License:SAP Netweaver
  8. AVR系列之TWI功能测试
  9. 逆序对算法c语言,归并排序求逆序对的代码(C语言)
  10. django mysql secure_auth_MySQL8.0的用户密码加密方式Django2.1兼容。
  11. 计算机网络通信设备的运行温度,什么是机房温度、湿度标准?
  12. 三字代码html,【涨知识】原来三字代码是这样来的!四字代码是什么?
  13. Ubuntu24.04下向日葵,CUDA,cuDNN的详细安装,亲测有效
  14. java实现列表拖动排序
  15. 大四去NTT面试软件实习生的个人总结
  16. 如何成为一名白帽子?
  17. 华为云计算IE面试笔记-桌面云中的用户组、虚拟机模板、模板虚拟机、虚拟机组和桌面组的关系及区别。发放完整复制和链接克隆虚拟机时,步骤有什么区别,要怎么选择桌面组?
  18. Linux内核版本和发行版本
  19. 腾讯云购买服务器操作步骤
  20. java怎么画八卦图_自己画八卦图怎么画?电脑绘制八卦图|八卦图的简单画法

热门文章

  1. qtablewidget控件居中_单元格Edi期间QTableWidgetItem中的文本居中
  2. 结合Zemax浅谈几何光学和信息光学中的成像,孔径光阑,视场光阑
  3. 在gamit中对rinex3的转换
  4. python中判断生肖和星座哪个准_星座准还是属相
  5. 华硕笔记本官网驱动如何下载
  6. 如何把PDF拆分成单页文档
  7. mysql查询自然周_Hive和MySQL中自然周保持一致的方法
  8. c语言制作单片机人机界面,基于51单片机自制触摸屏
  9. 利用5次shift漏洞破解win7密码
  10. 无法打开ONEDRIVE的解决方法【等待验证】