BUU [ACTF新生赛2020]Universe_final_answer
[ACTF新生赛2020]Universe_final_answer
首先查壳, 64bit 无壳
ida64位打开
main()
__int64 __fastcall main(int a1, char **a2, char **a3)
{__int64 v4; // [rsp+0h] [rbp-A8h] BYREFchar v5[104]; // [rsp+20h] [rbp-88h] BYREFunsigned __int64 v6; // [rsp+88h] [rbp-20h]
v6 = __readfsqword(0x28u);__printf_chk(1LL, "Please give me the key string:", a3);scanf("%s", v5);if ( (unsigned __int8)sub_860(v5) ){sub_C50(v5, &v4);__printf_chk(1LL, "Judgement pass! flag is actf{%s_%s}\n", v5);}else{puts("False key!");}return 0LL;
}
输入的内容是在v5里,然后在if里面要经过sub_860函数处理
sub_860()
bool __fastcall sub_860(char *a1)
{int v1; // ecxint v2; // esiint v3; // edxint v4; // er9int v5; // er11int v6; // ebpint v7; // ebxint v8; // er8int v9; // er10bool result; // alint v11; // [rsp+0h] [rbp-38h]
v1 = a1[1];v2 = *a1;v3 = a1[2];v4 = a1[3];v5 = a1[4];v6 = a1[6];v7 = a1[5];v8 = a1[7];v9 = a1[8];result = 0;if ( -85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 ){v11 = a1[9];if ( 30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400&& -103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 << 6) - 120 * v9 == -10283&& 71 * v6 + (v7 << 7) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855&& 5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944&& -54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222&& -83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258&& 81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559&& 101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308 ){return 99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697;}}return result;
}
第一看看到这个函数觉得挺离谱的,一个if里面塞了这么多东西,要计算的话肯定不能自己手算,还是得用python写脚本吧,但是就这样子的脚本写起来也够呛的,逻辑挺简单的,但是难就难在怎么计算
通过观察发现这东西就是一个矩阵,十阶矩阵,要是我手算的话我肯定这辈子都算不出来。。。
查了查wp,发现他们都是使用了z3这个python的库来解决这个方程的
利用python的Z3库可以进行约束求解,即解任何方程(只要有解),常用的包括整数求解、有理数求解、位向量求解(二进制位运算求解)。
直接在vscode里面pip安装z3这个库,然后写脚本
from z3 import *
s = Solver()
v1 = Int('v1')
v2 = Int('v2')
v3 = Int('v3')
v4 = Int('v4')
v5 = Int('v5')
v6 = Int('v6')
v7 = Int('v7')
v8 = Int('v8')
v9 = Int('v9')
v11 = Int('v11')
s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
s.add(30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
s.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 * 64) - 120 * v9 == -10283)
s.add(71 * v6 + (v7 * 128) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855)
s.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
s.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
s.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
s.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
s.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
s.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697)
if s.check() == sat:result = s.model()
print(result)
得到了最后的结果
[v1 = 48,v6 = 95,v2 = 70,v4 = 82,v11 = 64,v3 = 117,v5 = 84,v7 = 121,v9 = 119,v8 = 55]
按顺序排列,然后在转换成字符之前要注意到,v1和v2,v6和v7他们的位置需要交换一下。
得到结果
F0uRTy_7w@
接下来是sub_C50函数处理
sub_C50()
unsigned __int64 __fastcall sub_C50(const char *a1, _BYTE *a2)
{size_t v4; // raxunsigned int v5; // edxint v6; // ediint v7; // ecx__int64 v8; // r8__int128 *v9; // rsiunsigned int v10; // ecxint v11; // eaxint v12; // ediint v13; // edxint v14; // eax_BYTE *v15; // rsi_BYTE *v16; // rcx_BYTE *v17; // r8int *i; // raxunsigned __int64 result; // rax__int128 v20[2]; // [rsp+0h] [rbp-48h] BYREF__int64 v21; // [rsp+20h] [rbp-28h]unsigned __int64 v22; // [rsp+28h] [rbp-20h]
v22 = __readfsqword(0x28u);memset(v20, 0, sizeof(v20));v21 = 0LL;v4 = strlen(a1); //10v5 = 0;v6 = 9;while ( v5 < v4 ) // 0 < 10{v7 = a1[v5++];v6 ^= v7;}if ( v6 ) //v6初始值为64{v8 = 0LL;v9 = v20; //数组首地址while ( 1 ){v9 = (__int128 *)((char *)v9 + 4); //v9 = v20[0] + 4v10 = v8 + 1; //v10 = 1LLv11 = v6 / 10; //v11 = 6v12 = v6 % 10; //v12 = 4*((_DWORD *)v9 - 1) = v12; LOBYTE(v13) = v12;v6 = v11;if ( !v11 )break;v8 = v10;}v14 = v8 - 1;v15 = a2;v16 = &a2[v10];v17 = &a2[v8];for ( i = (int *)v20 + v14; ; --i ){*v15 = v13 + 48;if ( v17 == v15 )break;v13 = *i;++v15;}}else{v16 = a2;}result = __readfsqword(0x28u) ^ v22;*v16 = 0;return result;
}
尝试静态分析,但是这个这个函数分析起来真的不太容易,回去再仔细看看main函数
if ( (unsigned __int8)sub_860(v5) ){sub_C50(v5, &v4);__printf_chk(1LL, "Judgement pass! flag is actf{%s_%s}\n", v5);}
这里我们得到了正确的v5,经过sub_C50函数处理后,下一步是一个printf操作,直接给出我们flag,所以直接放在Ubuntu里面运行
得到了flag
flag{F0uRTy_7w@_42}
确实是在这道题里学到了新的东西,有些逆向不好写的算法可以直接用z3正向求解(但是确实是水题)
sub_C50函数的动态分析:
在进入sub_C50函数前下断点,然后输入F0uRTy_7w@
,alt+t在16进制区域找到该字符串,然后开始F7单步步入,观察该字符串的变化,但是在循环中出现了这样的问题。
这边行不通,直接在printf函数处下断点,F7单步步入找到输出flag的关键跳转
这一步打印操作是在syscall这,但是它为什么能打印出来这些,还有为什么__printf_chk有两个%s%s却只有v5,但是却能打印出来
问题还没有完全被解决,应该还有后续,(其实是动态分析还没玩明白。。。)
BUU [ACTF新生赛2020]Universe_final_answer相关推荐
- [SUCTF2018]babyre [ACTF新生赛2020]fungame
文章目录 [SUCTF2018]babyre 惯用思维 常人思维 GAMEOVER [ACTF新生赛2020]fungame int __cdecl sub_401340(int a1) int __ ...
- BUUCTF Misc 穿越时空的思念 [ACTF新生赛2020]outguess [HBNIS2018]excel破解 [HBNIS2018]来题中等的吧
目录 穿越时空的思念 [ACTF新生赛2020]outguess [HBNIS2018]excel破解 [HBNIS2018]来题中等的吧 穿越时空的思念 下载文件 使用Audacity打开 点击图示 ...
- [BUUOJ] [RE] [ACTF新生赛2020] rome1
IDA 好久没写博客了,最近在刷re,这道题是我觉得十分有意义的一道题.故AC后总结分享给大家.不足之处请指正. 分析 直接导入IDA shift +F12 双击后按 ctrl + x跳转到被调用的函 ...
- BUUCTF-MISC-[BJDCTF2020]你猜我是个啥~[ACTF新生赛2020]outguess
文章目录 1.[BJDCTF2020]你猜我是个啥 2.秘密文件 3.[SWPU2019]神奇的二维码 4.[BJDCTF2020]一叶障目 5.[BJDCTF2020]just_a_rar 6.[B ...
- re学习笔记(59)BUUCTF - re - [ACTF新生赛2020]Oruga
新手一枚,如有错误(不足)请指正,谢谢!! 题目链接:[ACTF新生赛2020]Oruga IDA64位载入,进入main函数 进入sub_78A()函数 类似于象棋里面的'车'吧,不过这个要走到障碍 ...
- BUUCTF——[ACTF新生赛2020]SoulLike——使用angr解
64位无壳.IDApro打开,查看main函数 逻辑很简单,我们来查看sub_83A函数.点进去,toobig 看了其他博客. 我们需要将ida /ctg目录下的hexrays.cfg文件中的MAX_ ...
- buu-[ACTF新生赛2020]Universe_final_answer
64位 查看字符串 跟进main函数 __int64 __fastcall main(__int64 a1, char **a2, char **a3) {__int64 v4; // [rsp+0h ...
- [ACTF新生赛2020]fungame
32位无壳 简单异或,解出来是 Re_1s_So0_funny but没有那么简单,这里只有16字节.继续分析: 这里出现了栈溢出: 4013BA函数的参数source 也就是v4(我们的flag) ...
- [ACTF新生赛2020]easyre
脱壳 使用exeinfo查看文件,发现有upx,使用upxshell解压缩.之后放进IDA中. 查看程序 很明显V4和v16都是个数组.可以看出是将v4的每个值(一共12个),去和data的那个数组去 ...
最新文章
- 未来到底是什么样子?
- 实用网站和在线工具推荐
- POI按照源单元格设置目标单元格格式
- python开发系统-python3+django2开发一个简单的人员管理系统
- 【C 语言】结构体 ( 结构体变量内存操作 | 通过 “ . “ 操作符操作结构体内存空间 | 通过 “ -> “ 操作符操作结构体内存空间 )
- VTK:几何对象之Pyramid
- 链式延迟执行DOME
- R 保存包含中文的 eps 图片--showtext
- 08flask中get和post请求。
- R语言的cpp扩展支持Rcpp模块介绍
- static在实例Extends、Overload中理解
- 建站之星v2.7快速更换模版
- thinkpad x250装黑苹果教程_Thinpad T系列安装MAC OS 黑苹果教程
- 保护你的 Flutter 应用程序
- YOLO与voc格式互转,超详细
- 最大子矩阵(悬挂线)
- java语言程序设计第二版 张思民_java语言程序设计(张思民编著)习题答案.doc
- iPhone重启软件Veresk的使用教程
- hdfs orc格式_HIVE存储格式ORC、PARQUET对比
- Kendo-UI学习 DataSource 数据源属性说明(二)
热门文章
- 【转】Guide to Elliptic Curve Cryptography(ECC椭圆曲线算法1)
- 谈软件系统的标准化和产品化
- 如何回复SCI审稿人评审意见(response letter)
- 直播平台源码实现网易云音乐样式的字幕
- JavaScript图片轮播案例
- tomcat处理html流程,基于Tomcat运行HTML5 WebSocket echo实例详解
- 腾讯云CPU处理器Intel Ice Lake主频2.7GHz睿频3.3GHz)
- 520被女朋友三番两次拉黑后,我用 Python 写了个“舔狗”必备神器
- 网站域名服务器加密,网站域名利用https防劫持方法
- 齐岳定制|Cyclopropene-PEG-Xylan|环丙烯-聚乙二醇-木聚糖