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.rhkb.cn/news/253177.html

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

相关文章

【开源】SpringBoot框架开发大病保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大病保险管理2.4 大病登记管理2.5 保险审核管理 三、系统详细设计3.1 系统整体配置功能设计3.2 大病人员模块设计3.3 大病保险模块设计3.4 大病登记模块设计3.5 保险审核模块设计 四、…

关于Django部署

首先了解一下开发环境服务器跟生产环境服务器有何不同。 一、我们通过 python manage.py runserver 启动开发环境服务器&#xff0c;这条命令背后做了哪些事情&#xff1f; 1、首先加载Django项目的设置&#xff08;settings&#xff09; 2、检查数据库迁移&#xff0c;确保数…

本地缓存Ehcache的应用实践 | 京东云技术团队

java本地缓存包含多个框架&#xff0c;其中常用的包括&#xff1a;Caffeine、Guava Cache和Ehcache&#xff0c; 其中Caffeine号称本地缓存之王&#xff0c;也是近年来被众多程序员推崇的缓存框架&#xff0c;同时也是SpringBoot内置的本地缓存实现。但是除了Caffeine之外&…

Cocos creator 3.x 刚体组件碰撞无效

Cocos creator 3.x 刚体组件碰撞无效 问题描述&#xff1a;只有一个circleCollider2D时&#xff0c;可以在碰撞时正确输出结果&#xff0c;但是当我在外围加了一个circle之后&#xff0c;期望character进入圆圈范围时就触发方法&#xff0c;此时原代码失效 import { _decorat…

Kubernetes基础(十四)-k8s网络通信

1 k8s网络类型 2 Pod网络 2.1 同一pod内不同容器通信 Pod是Kubernetes中最小的可部署单元&#xff0c;它是一个或多个紧密关联的容器的组合&#xff0c;这些容器共享同一个网络命名空间和存储卷&#xff0c;因此Pod中的所有容器都共享相同的网络命名空间和IP地址——PodIP&a…

JVM 性能调优 - 四种引用(4)

为什么会有四种引用 我们先回顾下在 Java 虚拟机内存体系(1) 中提到了的垃圾回收算法 1、引用计数法 原理:给对象添加一个引用计数器,每当有一个地方引用它,计数器的值就加一。每当有一个引用失效,计数器的值就减一。当计数器值为零时,这个对象被认为没有其他对象引用,…

【Java安全】ysoserial-URLDNS链分析

前言 Java安全中经常会提到反序列化&#xff0c;一个将Java对象转换为字节序列传输&#xff08;或保存&#xff09;并在接收字节序列后反序列化为Java对象的机制&#xff0c;在传输&#xff08;或保存&#xff09;的过程中&#xff0c;恶意攻击者能够将传输的字节序列替换为恶…

24.云原生ArgoCD高级之钩子

云原生专栏大纲 文章目录 Argo CD钩子如何定义钩子钩子删除策略 Argo CD钩子 Argo CD 是一个用于部署和管理 Kubernetes 应用程序的工具&#xff0c;它提供了一种声明式的方式来定义和自动化应用程序的部署过程。Argo CD 钩子&#xff08;Hooks&#xff09;是一种机制&#x…

ctfshow-web11~20-WP

web11 根据提示,查询对ctfshow域名进行dns查询,查看TXT记录 阿里云查询链接:阿里云网站运维检测平台 获取flag成功 web12 根据题目提示,我们访问robots.txt,获取到后台地址 然后我们访问一下后台

SQL--DQL

DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记 录。 查询关键字: SELECT 在一个正常的业务系统中&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访问企业官网、电商网站&#xff0c; 在这…

Linux内核与驱动面试经典“小”问题集锦(4)

接前一篇文章&#xff1a;Linux内核与驱动面试经典“小”问题集锦&#xff08;3&#xff09; 问题5 问&#xff1a;Linux内核中内存分配都有哪些方式&#xff1f;它们之间的使用场景都是什么&#xff1f; 备注&#xff1a;这个问题是笔者近期参加蔚来面试时遇到的一个问题。这…

Maven构建OSGI+HttpServer应用

Maven构建OSGIHttpServer应用 官网&#xff08;https://eclipse.dev/equinox/server/http_in_equinox.php&#xff09;介绍有两种方式&#xff1a; 一种是基于”org.eclipse.equinox.http”包的轻量级实现&#xff0c;另一种是基于”org.eclipse.equinox.http.jetty”包&#…

『 C++ - STL 』unordered_xxx系列关联式容器及其封装(万字)

文章目录 &#x1f3a1; unordered系列关联式容器&#x1f3a1; 哈希表的改造&#x1f3a2; 节点的设置与总体框架&#x1f3a2; 迭代器的封装&#x1f3a0; 迭代器的框架&#x1f3a0; operator()运算符重载&#x1f3a0; 其余成员函数/运算符重载 &#x1f3a2; 迭代器begin(…

ORM模型类

模型 创建两个表 创建模型类 from django.db import models# Create your models here. class BookInfo(models.Model):name models.CharField(max_length10, uniqueTrue) # 书名pub_date models.DateField(nullTrue) # 发布时间read_count models.IntegerField(default…

【TCP/IP】用户访问一个购物网站时TCP/IP五层参考模型中每一层的功能

当用户访问一个购物网站时&#xff0c;网络上的每一层都会涉及不同的协议&#xff0c;具体网络模型如下图所示。 以下是每个网络层及其相关的协议示例&#xff1a; 物理层&#xff1a;负责将比特流传输到物理媒介上&#xff0c;例如电缆或无线信号。所以在物理层&#xff0c;可…

ElastAlert 错误日志告警

文章目录 前言一、ElastAlert 概览1.1 简介1.2 ElastAlert 特性 二、ElastAlert 下载部署2.1 安装 Python3 环境2.2 下载 ElastAlert2.3 部署 ElastAlert 三、接入平台3.1 对外接口层3.2 服务层 前言 ElastAlert 是 Yelp 公司基于 python 开发的 ELK 日志告警插件&#xff0c;…

vue electron应用调exe程序

描述 用Python写了一个本地服务编译成exe程序&#xff0c;在electron程序启动后&#xff0c;自动执行exe程序 实现 1. 使用node的child_process模块可以执行windows执行&#xff0c;通过指令调exe程序 // electron/index.js var cp require("child_process"); /…

C++泛编程(3)

类模板基础 1.类模板的基本概念2.类模板的分文件编写3.类模板的嵌套 在往节内容中&#xff0c;我们详细介绍了函数模板&#xff0c;这节开始我们就来聊一聊类模板。C中&#xff0c;类的细节远比函数多&#xff0c;所以这个专题也会更复杂。 1.类模板的基本概念 和函数模板一样…

AES算法:数据传输的安全保障

在当今数字化时代&#xff0c;数据安全成为了一个非常重要的问题。随着互联网的普及和信息技术的发展&#xff0c;我们需要一种可靠的加密算法来保护我们的敏感数据。Advanced Encryption Standard&#xff08;AES&#xff09;算法应运而生。本文将介绍AES算法的优缺点、解决了…

【调试】pstore原理和使用方法总结

什么是pstore pstore最初是用于系统发生oops或panic时&#xff0c;自动保存内核log buffer中的日志。不过在当前内核版本中&#xff0c;其已经支持了更多的功能&#xff0c;如保存console日志、ftrace消息和用户空间日志。同时&#xff0c;它还支持将这些消息保存在不同的存储…