BeginCTF2024 RE 部分复现

8. arc

上面一托混淆,左边似乎是三个东西相乘

单独取出最左边一托打印,可以得到大数组

接下来要解密,原代码非常混乱,我们先整理一下,简单去混淆

print
(all([[data][a][d] == e for a, b in enumerate([[int(a) for a in bin(sum((ord(b) << 6 ^ 4102 - a ^ c for c in b'beginCTF'))).replace('0b', '')] for a, b in enumerate(input('[+]Flag: '))]) for d,e in iter #迭代器((enumerate(b)))])
)

a应该是行数索引,b是输入的字符,经过bin(sum((ord(b) << 6 ^ 4102 - a ^ c for c in b'beginCTF')))转化成一个二进制数,应该要和大数组里对应行里的一行数字相同

data = [[1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0], [1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0], [1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0], [1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0], [1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0], [1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0], [1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0], [1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0], [1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0], [1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0], [1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0], [1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0], [1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0], [1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0], [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0], [1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0], [1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0], [1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0], [1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0], [1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0], [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0], [1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0], [1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0], [1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0], [1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0], [1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0], [1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0], [1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0], [1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0], [1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0], [1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0], [1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0], [1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0]]
# 本文作者:Yuro@Yuro的博客
# 本文链接:https://yurogod.github.io/ctf/events/BeginCTF-2024/
# 版权声明:本站所有文章除特别声明外,均采用 (CC)BY-NC-SA 许可协议。转载请注明出处!
for i, lst in enumerate(data): #i是索引,lst是子序列(每一行)for j in range(32, 128): #爆破有效字符n = int("".join([str(x) for x in lst]), 2) #把每一行的数字连起来变成二进制,再转换为十进制if sum((j << 6 ^ 4102 - i ^ key for key in b'beginCTF')) == n: print(chr(j), end="")break
#begin{Y@u_aRe_g00d_aT_play1ng_witH_sNake3}
9. stick game

源码里搜一下score

改一下,没吊用

中间有一坨,后来才知道是ob混淆

Obfuscator.io Deobfuscator

用网站去混淆

救赎之道,就在其中 begin{y0u_re4l1y_g07_1337427_74e96c14c0c79977b52a15ba559bcf30}

(似乎也可以在case6那里改分数)

10. superguesser

start函数往下翻,有一坨赋值,把数据按C键转成代码,去掉花(可能是花搞不清楚)——也并不能还原伪代码,不过可以大致看看

while这里进行了异或,可能是加密逻辑

if这里应该是判断比对密文

照理来说应该动调把加密逻辑调出来,但是太麻烦,不如先根据密文猜测

动调取一下密文,寻找memcmp函数调用的位置,找cmp指令

67行if下个断点,一路F7

进去,rdx,rcx寄存器里好像有字符串,但是没到cmp,往下走几步

拼接成了字符串

密文和flag头单字节异或一下

结合伪代码中的51

可以猜测每一位异或从51递增的数

#superguesser wp
enc = [0x51, 0x51, 0x52, 0x5F, 0x59, 0x43, 0x5D, 0x5F, 0x59, 0x49, 0x5A, 0x59, 0x56, 0x2E, 0x26, 0x1D, 0x2A, 0x37, 0x1A, 0x27, 0x29, 0x17, 0x28, 0x24, 0x2A, 0x38, 0x25, 0x21, 0x3D, 0x0F, 0x32, 0x3A, 0x3C, 0x3D, 0x36, 0x33, 0x2A]exm = 'begin{'
flag = ''
#for i in range(6):
#    print(enc[i]^ord(exm[i]))
for i in range(len(enc)):flag += chr(enc[i]^(i+51))
print(flag)
#begin{debugging_is_an_anathor_choice}
11. not main

具体的原理在官方WP里讲了,看不太懂,就记录一下大致流程吧

主函数看起来是个tea,但是题目都告诉我们not main,说明这个不对

找一找有个Hander函数,一般是异常处理时跳转的函数

有个xxtea

这里应该是真实的加密过程

应该是key

然后就是调密文,动调调不了,有反调试

请教dalao后得知关键代码在__scrt_common_main_sehinitterm

这个函数调用了这两个地址之间的所有函数,参数是两个函数指针

一个个看,点进第三个可以看到两个疑似密文的地址,点进第四个则是触发Handler的部分

第四个sub_51010实际上就是反调试的位置,也是Handler的调用位置

可以发现,一旦检测到被调试,Handler就不会触发

第三个sub_51000则是:

不知道哪一个是密文,X查一下引用

unk_48503C没有其他引用,unk_485018引用分别在Handler和main,有可能是main里的假密文

再看一下汇编,这里把offset unk_48503Coffset unk_485018的地址进行了异或。

另一处Handler内的unk_485018引用则再次进行了这个操作,也就是说等于没异或

所以如果真逻辑在Handler内,unk_485018就是没用的数据

真正的密文就是unk_48503C

由于TEA系加密每次需要的原始数据是2个32位无符号整数,所以取数据时注意一下

也就是8个数,两个一组,加密四轮

密钥是true

抄个XXTEA脚本跑一下——乱码

可能主函数TEA不是假的,又进行了TEA加密

看一下__scrt_common_main_seh

发现调用Handler在main之前,可能XXTEA之后又进行了TEA

查一下明文的引用

可以看到main当中的明文是从Handler中引用的,与之前的猜想呼应

只不过tea加密用的是另一套密钥fake

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2)+(y>>3^z<<4))^((sum^y)+(key[(p&3)^e]^z)))
void btea(uint32_t* v, int n, uint32_t const key[4])
{uint32_t y, z, sum;unsigned p, rounds, e;if (n > 1){rounds = 6 + 52 / n;	//这里可以说是预定义值,n=2是rounds=32sum = 0;z = v[n - 1];do{sum += DELTA;e = (sum >> 2) & 3;for (p = 0; p < n - 1; p++)        //注意这里的p是从0~n-1{y = v[p + 1];z = v[p] += MX;}y = v[0];z = v[n - 1] += MX;        //这里的MX中传入的p=n-1} while (--rounds);}else if (n < -1){n = -n;rounds = 6 + 52 / n;sum = rounds * DELTA;y = v[0];do{e = (sum >> 2) & 3;for (p = n - 1; p > 0; p--)    //注意这里的p是从n-1~0,和上面是反过来的{z = v[p - 1];y = v[p] -= MX;}z = v[n - 1];y = v[0] -= MX;    //这里的MX中传入的 p=0sum -= DELTA;} while (--rounds);}
}
void detea(uint32_t* v, uint32_t* k) {uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;uint32_t delta = 0x9e3779b9;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i < 32; i++) {v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);sum -= delta;}v[0] = v0; v[1] = v1;
}
int main()
{uint32_t v[8] = { 0xCFBE0F1B, 0x05F3083F, 0x4220E43B, 0x3383AFEE, 0xFA3237CE, 0xECADA66E, 0xA8D47CA7, 0xEFC51077 };uint32_t k[4] = { 116,114,117,101 };//trueuint32_t fk[4] = { 0x66,0x61,0x6B,0x65 };//fakeint i, n = 8;btea(v, -n, k);//负号是解密for (i = 0; i < 8; i += 2)detea(v + i, fk);printf("%s", v);//begin{not_main_is_matter!}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/459133.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

16:定时器和计数器

定时器和计数器 1、定时器和计数器的介绍2、定时器是如何工作3、寄存器4、51单片机定时器简介&#xff08;数据手册&#xff09;5、定时器中的寄存器&#xff08;数据手册&#xff09;5.1、TCON&#xff08;定时器控制寄存器&#xff09;5.2、TMOD&#xff08;工作模式寄存器&a…

2024美赛数学建模ABCDEF题思路代码

--------------------2024美国大学生数学建模竞赛&#xff08;美赛&#xff09;思路&代码---------------------------- 赛题翻译&#xff1a;2024美赛ABCDEF赛题翻译 问题A&#xff08;数据分析题&#xff09;&#xff1a;资源可用性和性别比例&#xff08;MCM&#xff09…

LeetCode1365之切披萨的方案数(相关话题:二维前缀和,动态规划)

题目描述 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; A &#xff08;表示苹果&#xff09;和 . &#xff08;表示空白格子&#xff09;。你需要切披萨 k-1 次&#xff0c;得到 k 块披萨并送给别人。 切披萨的每一刀&#xf…

CS50x 2024 - Lecture 1 - C

本周学习C语言&#xff0c;重点是函数、变量、条件语句和循环。 05:11介绍了编程语言的转换过程&#xff0c;从源代码到机器码&#xff0c;以及编译器的作用。 编译器是将一种语言翻译成另一种语言的程序 09:18使用CS50.dev进行编程&#xff0c;介绍了VS Code和命令行界面的…

信钰证券:零基础入门,教你如何学习炒股技能!

股票市场是一个充满时机和风险的地方&#xff0c;不少投资者都想经过炒股来完成财富增值的方针。但炒股赚钱并不是一件十分容易的事情&#xff0c;对于新手怎样学炒股&#xff0c;信钰证券下面就为我们详细介绍一下。 股票是一种有价证券&#xff0c;其代表的是上市公司的所有…

点云——噪声(代码)

本人硕士期间研究的方向就是三维目标点云跟踪&#xff0c;对点云和跟踪有着较为深入的理解&#xff0c;但一直忙于实习未进行梳理&#xff0c;今天趁着在家休息对点云的噪声进行梳理&#xff0c;因为预处理对于点云项目是至关重要的&#xff0c;所有代码都是近期重新复现过。 这…

识别CMS指纹与WAF识别

目录 识别CMS指纹 1 什么是CMS指纹&#xff1f; 2 常见的CMS指纹 3 识别CMS指纹的方法有哪些&#xff1f; &#xff08;1&#xff09;分析HTTP响应头&#xff0c;识别CMS的特定标头。 &#xff08;2&#xff09;通过配置文件/特殊文件 &#xff08;3&#xff09;分析网站…

【MySQL】-11 MySQL 架构及优化原理

MySQL 架构及优化原理 1 MySQL逻辑架构2 MySQL逻辑架构整体分为三层 :3 MySQL查询过程MySQL 整个查询执行过程&#xff0c;总的来说分为 5 个步骤 :3.1 客户端/服务端通信协议3.2 查询缓存3.3 查询优化3.4 查询执行引擎3.5 返回结果给客户端 4 查询系统性能1 分析查询语句2 索…

2019年江苏省职教高考计算机技能考试——一道程序改错题的分析

题目&#xff1a;函数将str字符串中的5个数字字符串转换为整数&#xff0c;并保存在二维数组m的最后一行&#xff0c;各元素为3、-4、16、18、6。并经函数move处理后&#xff0c;运行结果如下&#xff1a; 18 6 3 -4 16 16 18 6 3 -4 -4 16 …

Linux操作系统基础(一):操作系统概述

文章目录 操作系统概述 一、计算机分类 二、计算机组成 三、操作系统概述 四、操作系统分类 操作系统概述 一、计算机分类 计算机一般分为个人计算机&#xff08;笔记、台式机&#xff09;与 企业级服务器&#xff08;1U、2U、机柜、塔式、刀片&#xff09;两种形式。 二…

[NISACTF 2022]easyssrf

它提示我们输入 那我们输入file:///flag file:// 访问本地文件系统 它提醒我们输file:///fl4g 它提醒我们输ha1x1ux1u.php 看到代码stristr($file, “file”)当我们输入file它会提示我们输了 啥意思可以前面加个/ 也可以通过read读取 思路都是前面加/不等于flag绕过 filephp://…

基于SSM的餐厅点菜管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的餐厅点菜管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring …