测试文件下载:https://adworld.xctf.org.cn/media/task/attachments/fa4c78d25eea4081864918803996e615

1.准备

获得信息

  1. 64位文件

2.IDA打开

选择main函数,反编译为C代码。

 __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
const char *v3; // rsi
signed __int64 v4; // rbx
signed int v5; // eax
char v6; // bp
char v7; // al
const char *v8; // rdi
__int64 v10; // [rsp+0h] [rbp-28h] v10 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL);
if ( strlen(&s1) != || (v3 = "nctf{", strncmp(&s1, "nctf{", 5uLL)) || *(&byte_6010BF + ) != )
{
LABEL_22:
puts("Wrong flag!");
exit(-);
}
v4 = 5LL;
if ( strlen(&s1) - > )
{
while ( )
{
v5 = *(&s1 + v4);
v6 = ;
if ( v5 > )
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == )
{
v7 = sub_400650((char *)&v10 + , v3);
goto LABEL_14;
}
if ( v5 == )
{
v7 = sub_400660((char *)&v10 + , v3);
goto LABEL_14;
}
}
else
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == )
{
v7 = sub_400670(&v10, v3);
goto LABEL_14;
}
if ( v5 == )
{
v7 = sub_400680(&v10, v3);
LABEL_14:
v6 = v7;
goto LABEL_15;
}
}
LABEL_15:
v3 = (const char *)HIDWORD(v10);
if ( !(unsigned __int8)sub_400690(asc_601060, HIDWORD(v10), (unsigned int)v10) )
goto LABEL_22;
if ( ++v4 >= strlen(&s1) - )
{
if ( v6 )
break;
LABEL_20:
v8 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( asc_601060[ * (signed int)v10 + SHIDWORD(v10)] != )
goto LABEL_20;
v8 = "Congratulations!";
LABEL_21:
puts(v8);
return 0LL;
}

打开字符串的视图,我们可以看到

.data: asc_601060      db '  *******   *  **** * ****  * ***  *#  *** *** ***     *********',

2.1 代码分析

 __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
signed __int64 v4; // rbx
signed int v5; // eax
char v6; // bp
char v7; // al
const char *v8; // rdi
__int64 v10; // [rsp+0h] [rbp-28h] v10 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL); if ( strlen(&s1) != || strncmp(&s1, "nctf{", 5uLL) || *(&byte_6010BF + ) != ) //len(s1) = 24, s1开头为'nctf',
{
LABEL_22:
puts("Wrong flag!");
exit(-);
}
v4 = 5LL; //flag总长24,已知5个长度,v4表示输入的表示方向的字符数。
if ( strlen(&s1) - > )
{
while ( )
{
v5 = *(&s1 + v4); //v5 = s1[5]
v6 = ;
if ( v5 > 'N' )//v5 > 'N'
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == 'O' ) //1. 当v5 == 'O'的情况,表示左移
{
v7 = sub_400650((char *)&v10 + , v3); //v10--,表示位置的列数-1,v7判断是否越界(越界返回:FALSE, 未越界返回:TRUE)
goto LABEL_14;
}
if ( v5 == 'o' ) //2. 当v5 == 'o‘的情况,表示右移
{
v7 = sub_400660((char *)&v10 + , v3); //v10++,表示位置的列数+1,
goto LABEL_14;
}
} else//v5 < 'N'
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == '.') //3. v5 == '.'的情况, 表示上移
{
v7 = sub_400670(&v10, v3); //v10--,表示位置的行数-1,
goto LABEL_14;
}
if ( v5 == '' ) //4. v5=='0'的情况,表示下移
{
v7 = sub_400680(&v10, v3); //v10++, 表示位置的行数+1
LABEL_14:
v6 = v7; //赋值给v6,下面判断走迷宫时,是否越界
goto LABEL_15;
}
} LABEL_15:
if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v10), v10) )//判断该位置的字符是' ', '#'或者'*'中的哪种,如果是'*'则,返回再次寻路
goto LABEL_22;
if ( ++v4 >= strlen(&s1) - ) //因为最后以'}'结尾,所以strlen(s1) - 1。我们需要找到中间18个字符
{
if ( v6 )//判断是否越界(未越界退出循环)
break;
LABEL_20:
v8 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( asc_601060[ * (signed int)v10 + SHIDWORD(v10)] != )//判断是否到达'#'处,没有到达,继续返回循环,进行移动
goto LABEL_20;
v8 = "Congratulations!";
LABEL_21:
puts(v8);
return 0LL;
}

通过代码分析,能够判断出那一串字符实际上就是一个迷宫,通过'.', '0', 'O', 'o'来控制移动,V10实际上就是一个二维数组,一维表示X轴,二维表示Y轴。

2.2 方向判断

在汇编代码中

.text:00000000004006B7                 mov     dword ptr [rsp+28h+var_28+],
.text:00000000004006BF mov dword ptr [rsp+28h+var_28],

我们能够知道,v9高位表示x轴,v9低位表示y轴,

通过函数

__int64 __fastcall sub_400690(__int64 a1, int a2, int a3)
{
__int64 result; // rax result = *(unsigned __int8 *)(a1 + a2 + 8LL * a3);//a1是迷宫,a2是列,a3是行。通过行列计算迷宫对应位置的字符
LOBYTE(result) = (_DWORD)result == || (_DWORD)result == ;//如果是' '或者'#‘返回TRUE,是'*’返回FALSE
return result;
}

sub_400690函数中是a2+a3*8,即a3表示行,a2表示列。返回到调用函数处,即v10高位表示列,低位表示行。那么就可以判断出'O','o'表示左右,'.','0'表示上下

2.3 迷宫表示

通过a2+a3*8我们也能了解到这个迷宫有8行,总共64个字符,也就是8x8的迷宫,表示出来就是。

******
***
******
*****
**#*
******
***
********

2.4 解迷宫

起点(1,1),只能走0,要走到‘#’,找到路径右下右右下下左下下下右右右右上上左左

写出脚本

str = "右下右右下下左下下下右右右右上上左左"
str = str.replace('上', '.')
str = str.replace('下', '')
str = str.replace('左', 'O')
str = str.replace('右', 'o') str = 'nctf{' + str + '}' print(str)

3.get flag!

nctf{oo0oo00O000oooo..OO}

攻防世界--maze的更多相关文章

  1. 逆向-攻防世界-maze

    题目提示是走迷宫. IDA载入程序分析. 输入字符长度必须是24,开头必须是nctf{,结尾必须是}.在125处按R就可以变成字符. sub_400650和sub_400660是关键函数,分析sub_ ...

  2. 攻防世界 maze NJUPT CTF 2017

    迷宫题 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3) 2 { 3 signed __int64 mid_i; // rbx 4 ...

  3. CTF--web 攻防世界web题 robots backup

    攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...

  4. CTF--web 攻防世界web题 get_post

    攻防世界web题 get_post https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5 ...

  5. 攻防世界 web进阶练习 NewsCenter

    攻防世界 web进阶练习 NewsCenter   题目是NewsCenter,没有提示信息.打开题目,有一处搜索框,搜索新闻.考虑xss或sql注入,随便输入一个abc,没有任何搜索结果,页面也没有 ...

  6. 【攻防世界】高手进阶 pwn200 WP

    题目链接 PWN200 题目和JarvisOJ level4很像 检查保护 利用checksec --file pwn200可以看到开启了NX防护 静态反编译结构 Main函数反编译结果如下 int ...

  7. XCTF攻防世界Web之WriteUp

    XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...

  8. 攻防世界 | CAT

    来自攻防世界官方WP | darkless师傅版本 题目描述 抓住那只猫 思路 打开页面,有个输入框输入域名,输入baidu.com进行测试 发现无任何回显,输入127.0.0.1进行测试. 发现已经 ...

  9. 攻防世界 robots题

    来自攻防世界 robots [原理] robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在, ...

随机推荐

  1. Spring的事物原理

    在Spring中把非功能性的事物管理代码以切面的形式进行管理,只需要声明事物即可启用事物管理. 本质:最终执行的还是java.sql.Connection的setAutoCommit(),commit ...

  2. 前端每日实战:25# 视频演示如何用纯 CSS 创作一个慧星拖尾效果的 loader 动画

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/YLRLaM 可交互视频教程 此视频 ...

  3. windows命令整理

    本文只是作为知识整理,尽可能的收集一些常用的内网指令.本人原伸手党一枚,希望这些内容对新人有用,大牛可自行忽略. 0x00 内网信息收集 一.单机基础信息收集 如果是获得第一台初始主机的权限的话,我们 ...

  4. jquery常用用法

    1.$("prve + next" )                          选择紧接着在perve后的next元素2.$("#div1 > *&quo ...

  5. JavaScript中数组的操作方法总汇

    Array(数组)是JavaScript中最为常用的类型了.ECMAScript中的数组都是数据的有序列表.数组中可以保存任何类型的数据.数组的大小是可以动态调整的,既可以随着数据的添加自动增长以容纳 ...

  6. 攻防世界 | level0

    先反编译 : int __cdecl main(int argc, const char **argv, const char **envp) { write(1, "Hello, Worl ...

  7. scau 17967 大师姐唱K的固有结界

    17967 大师姐唱K的固有结界 该题有题解 时间限制:1000MS  内存限制:65535K 提交次数:41 通过次数:8 收入:107 题型: 编程题   语言: G++;GCC;VC Descr ...

  8. Fault Contract

    The Fault Contract sample demonstrates how to communicate error information from a service to a clie ...

  9. 001-notepad++下载安装、添加右键

    一.下载 1.1.下载地址:https://notepad-plus-plus.org/ 一般下载 /1.2 1.2.解压至指定路径下即可 1.3.注册表添加鼠标右键 添加鼠标右键, 保存成reg执行 ...

  10. MongoDb python连接

    方式一:简写 client = MongClient() 方式二:指定端口和地址 client = MongoClient('localhost':27017) 方式三:使用URI  --统一资源定位 ...