蜀道山CTF<最高的山最长的河>出题记录

出这道题的最开始感觉就是,因为现在逆向的形式好多,我最开始学习的时候,经常因为很多工具,或者手段完全不知道,就很懵逼,很多师傅都出了各种类型的,我就想着给以前的"自己"出一道正常exe,慢慢调的题,为了不那么简单,我就选择了C++(究极混淆,可能比rust好点),让大家无聊了,慢慢调着玩,哈哈,轻喷~

哈哈,出这道题的时候,那个时候BLG被干烂了,给我郁郁了一阵,就取了这个名字

其中

这里我把第一行给改了,大家随便找个正常exe改了就行,下面那里单纯是我写着玩的,哈哈,出题人的小乐趣

相信大家进来就可以找到主函数了,可能有些师傅会困惑,中间有个trycatch的地方,那个就是我拿来迷惑大家的,哈哈,然后你输入的长度不对,可能也会导致报错,可能也算另类的"反调试"?

这里为了方便,我就直接放源码吧,师傅们也可以拿去学习或者改一下出题也行

(以前学习很多都是白嫖很多师傅们的资源学习,传承一下下)

#include <iostream>
#include <string>
#include <vector>
#include <cstdint>
using namespace std;
const std::string base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const vector<unsigned long> enc ={165,100,159,4,57,183,166,23,34,205,38,77,125,16,130,219,133,219,39,57,66,60,30,165,34,205,38,77,125,16,130,219,214,55,104,128,177,249,21,25,68,24,66,36,143,120,162,44,};
const uint32_t key[] = { 'L', 'Z', 'S', 'D', 'S' };
//LZSDS{how_how_how_how_how_ow_ow_ow!}
std::vector<uint32_t> sub1234(const std::vector<uint32_t>& a) {std::vector<uint32_t> b;for (uint32_t i : a) {b.push_back((i >> (3 * 8)) & 0xFF);b.push_back((i >> (2 * 8)) & 0xFF);b.push_back((i >> (1 * 8)) & 0xFF);b.push_back((i >> (0 * 8)) & 0xFF);}if (b.size()!=48 ){throw std::runtime_error("!!!what will happen?");}return b;
}std::pair<uint32_t, uint32_t> tea(uint32_t v0, uint32_t v1) {const uint32_t delta = 0x9E3779B9;uint32_t sum = delta * 32;for (int i = 0; i < 32; ++i) {v1 -= ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]);v0 -= ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]);sum -= delta;}return std::make_pair(v0 ^ key[4], v1 ^ key[4]);}std::vector<uint32_t> to_tea(const std::vector<uint32_t>& a) {std::vector<uint32_t> result = a;std::vector<uint32_t> b;for (size_t i = 0; i < a.size() - 3; i += 4) {b.push_back((static_cast<uint32_t>(result[i + 3]) << (3 * 8)) +(static_cast<uint32_t>(result[i + 1]) << (2 * 8)) +(static_cast<uint32_t>(result[i + 2]) << (1 * 8)) +static_cast<uint32_t>(result[i]));}for (size_t i = 0; i < b.size() - 1; i += 2) {auto [v0, v1] = tea(b[i], b[i + 1]);b[i] = v0;b[i + 1] = v1;}return sub1234(b);
}std::vector<uint32_t> encode2(const std::string& str) {std::vector<uint32_t> a(str.begin(), str.end());std::vector<uint32_t> b;std::vector<uint32_t> h;for (size_t i = 0; i < a.size(); i += 3) {b.push_back(a[i] & 0b111111);b.push_back(a[i+1] & 0b111111);b.push_back(a[i+2] & 0b111111);b.push_back((((a[i]>>6) & 0b11)<<4)+(((a[i+1]>>6) & 0b11)<<2)+((a[i+2]>>6) & 0b11));}//魔改teafor (int i = 0; i < b.size(); ++i) {h.push_back(base64_table[b[i]]);//        cout<<char(h[i]);}cout<<endl;std::vector<uint32_t> encrypted = to_tea(h);//    for (uint32_t i : encrypted){//        cout<<i<<',';//    }return encrypted;
}
int main() {std::string in_put;while (true) {cout<<"input your flag:\n";std::cin >> in_put;if (in_put == "end") {break;}try{vector<uint32_t> ans = encode2(in_put);for (int i = 0; i < enc.size(); ++i) {if (ans[i]!=enc[i]){std::cout << "No!!!!" << std::endl;exit(0);}}cout<<"yoxi! you are right!!!" << std::endl;return 0;}catch (const std::exception& e){cout<<"wow ! look where you are!"<<endl;cout<<"!!!what will happen?"<<endl;cout<<"come on!"<<endl;string flag;cin>>flag;cout<<"wrong!!"<<endl;}}return 0;
}

这里我就是自定义base编码过程,没有换表,肯定有很多师傅写了很多换表了,我们换换口味,就是标准表,嘿嘿嘿(中间解法多样,条条大路通罗马)

但是我看见有师傅是还是通过拿到的不一样的表搞出来的,最后那个可能有个多解.

毕竟加密都是对于flag,那样一步到位了(很有耐心的师傅)

这里我是改了base的编码过程,每一个取6位,让最后每个剩下的两个再组成一个数据,得到的base,拿去tea,tea有五个密钥,最后那一个就是异或了结果

然后这是我当时自己写的解密脚本,给师傅们借鉴下

#include <iostream>
#include <string>
#include <vector>
#include <cstdint>
using namespace std;
const vector<unsigned long> enc ={165,100,159,4,57,183,166,23,34,205,38,77,125,16,130,219,133,219,39,57,66,60,30,165,34,205,38,77,125,16,130,219,214,55,104,128,177,249,21,25,68,24,66,36,143,120,162,44,};
const std::string base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const unsigned long key[] = { 'L', 'Z', 'S', 'D', 'S' };
std::vector<unsigned long> dsub1234(const std::vector<unsigned long>& a) {std::vector<unsigned long> b;for (int i = 0; i < a.size(); i += 4) {b.push_back(((a[i] << (3 * 8)) ) + ((a[i + 1] << (2 * 8))) + ((a[i + 2] << (1 * 8)) ) + (a[i + 3] & 0xff));}return b;
}
int find1(int a){for (int i = 0; i < base64_table.size(); ++i) {if (a==int (base64_table[i])){
//            cout<<i;return i;}}
}
std::vector<unsigned long> sub1234(const std::vector<unsigned long>& a) {std::vector<unsigned long> b;for (unsigned long i : a) {unsigned int t[4]={i&0xFF,((i >> (2 * 8)) & 0xFF),((i >> (1 * 8)) & 0xFF),((i >> (3 * 8)) & 0xFF)};b.push_back(find1(t[0]));b.push_back(find1(t[1]));b.push_back(find1(t[2]));b.push_back(find1(t[3]));}cout<<endl;return b;
}
std::pair<unsigned long, unsigned long> tea(unsigned long v0, unsigned long v1) {const unsigned long delta = 0x9E3779B9;unsigned long sum = 0;for (int i = 0; i < 32; ++i) {sum += delta;v0 += ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]);v1 += ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]);}return std::make_pair(v0 , v1 );
}
std::vector<unsigned long> to_tea(const std::vector<unsigned long>& a) {std::vector<unsigned long> b=a;for (size_t i = 0; i < b.size() - 1; i += 2) {auto [v0, v1] = tea(b[i]^key[4], b[i + 1]^key[4]);b[i] = v0;b[i + 1] = v1;}return b;
}std::vector<unsigned long> decode(vector<unsigned long> str) {std::vector<unsigned long> m=dsub1234(str);//转换为八字节数据std::vector<unsigned long> encrypted = to_tea(m);//tea解密std::vector<unsigned long> a= sub1234(encrypted);//找到basestd::vector<unsigned long> b;//转换成给tea的参数for (size_t i = 0; i < a.size(); i += 4) {b.push_back((a[i])+(((a[i+3]>>4)&0b11)<<6));b.push_back(a[i+1]+(((a[i+3]>>2)&0b11)<<6));b.push_back(a[i+2]+((a[i+3]&0b11)<<6));}for (unsigned long i : b){cout<<char(i);}cout<<endl;return encrypted;
}
int main() {decode(enc);return 0;
}

这道题其实厉害的师傅,也可以考虑一下爆破,如果patch题目hook一下,三字节爆破一下就出来了,如果不会的师傅也可以去在base阶段采取爆破的做法,爆破感觉比手撕快多了~

最后出题有任何不合理的地方,欢迎师傅们指正,有任何问题也可以私聊我,如果有想和我一起交流re,学习的师傅也很欢迎.(抱拳)

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

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

相关文章

Quartus+Nios II for eclipse问题合集

由于对于FPGANIOS II 的工作需要&#xff0c;对工作过程中遇到的问题进行记录&#xff0c;持续更新。 1、BSP directory does not exist: . Stop.Nios II使用过程中遇到的一些问题2_error executing nios2-bsp-generate-files --bsp-di-CSDN博客https://blog.csdn.net/qq_39485…

AWTK VSCode 实时预览插件端口冲突的解决办法

AWTK XML UI 预览插件&#xff1a;在 vscode 中实时预览 AWTK XML UI 文件&#xff0c;在 Copilot 的帮助下&#xff0c;可以大幅提高界面的开发效率。 主要特色&#xff1a; 真实的 UI 效果。可以设置主题&#xff0c;方便查看在不同主题下界面的效果。可以设置语言&#xf…

开源项目低代码表单设计器FcDesigner获取表单的层级结构与组件数据

在使用开源项目低代码表单设计器FcDesigner时&#xff0c;获取和理解表单的层级结构非常关键。通过getDescription和getFormDescription方法&#xff0c;您可以清晰掌握表单组件的组织结构和层次关系。这些方法为操控表单的布局和配置提供了强大的支持。 源码地址: Github | G…

如何对AWS进行节省

AWS 云服务器的费用确实可能会让人感到高昂&#xff0c;尤其是在资源使用不当或配置过多的情况下。不过&#xff0c;通过一些策略的合理应用和优化&#xff0c;完全可以降低云服务的使用成本&#xff0c;实现高效节省。以下是九河云总结的几种主要的优化方法&#xff0c;帮助你…

Macmini中普通鼠标与TrackPad联动问题解决

入手了一款Macmini&#xff0c;然后接了一个普通鼠标&#xff0c;然后又买了一个TrackPad。 接下来&#xff0c;问题来了&#xff0c;这两个玩意之间是联动的&#xff0c;出现问题的地方在于鼠标滚轮对于页面内容滚动的方向上。 通常Windows系统中&#xff0c;鼠标滚轮向前&am…

基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】

&#x1f388;系统亮点&#xff1a;协同过滤算法、二维码识别&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框…

深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

目录 深入理解 JavaScript 中的 Array.find() 方法&#xff1a;原理、性能优势与实用案例详解 一、引言&#xff1a;为什么要使用Array.find() 二、Array.find()的使用与技巧 1、基础语法 2、返回值 3、使用技巧 三、Array.find()的优势与实际应用案例 1、利用返回引用…

安全、便捷、效率高,明达边缘计算网关助力制药装备企业远程调机

随着药厂对设备运维需求的增长&#xff0c;制药装备企业需要在提高运维效率的同时&#xff0c;降低人工及差旅成本。制药装备因其数据具有高度的保密性&#xff0c;要求运维工程师提供安全可靠的远程调试方式。本案例介绍了明达技术MBox20系列5口WIFI通用网关在制药装备上的应用…

HBase 开发:使用Java操作HBase

1、实战简介 HBase和Hadoop一样&#xff0c;都是用Java进行开发的&#xff0c;本次实训我们就来学习如何使用Java编写代码来操作HBase数据库。 实验环境&#xff1a; hadoop-2.7 JDK8.0 HBase2.1.1 2、任务 1、第1关&#xff1a;创建表 package step1; import java.io.IOE…

vulhub之log4j

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 漏洞简介 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 Apache Log4j 在应用程序中添加日志记录最…

【视觉SLAM】2-三维空间刚体运动的数学表示

读书笔记&#xff1a;学习空间变换的三种数学表达形式。 文章目录 1. 旋转矩阵1.1 向量运算1.2 坐标系空间变换1.3 变换矩阵与齐次坐标 2. 旋转向量和欧拉角2.1 旋转向量2.2 欧拉角 3. 四元数 1. 旋转矩阵 1.1 向量运算 对于三维空间中的两个向量 a , b ∈ R 3 a,b \in \R^3 …

Ubuntu22.04基于ROS2-Humble安装moveit2教程(亲测)

一、安装ROS2-Humble 1、参考&#xff1a;Ubuntu22.04安装ROS2-humble-CSDN博客 2、确保安装完成 source /opt/ros/humble/setup.bash 方法一&#xff1a;二进制安装 sudo apt install ros-humble-moveit* 方法二&#xff1a;安装源码编译 一、卸载二进制安装包 sudo a…

一些常见网络安全术语

1、黑帽 为非法目的进行黑客攻击的人&#xff0c;通常是为了经济利益。他们进入安全网络以销毁&#xff0c;赎回&#xff0c;修改或窃取数据&#xff0c;或使网络无法用于授权用户。这个名字来源于这样一个事实&#xff1a;老式的黑白西部电影中的恶棍很容易被电影观众识别&…

ISCTF 2024 web

ISCTF 2024 web 小蓝鲨的冒险 源码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); $a "isctf2024"; $b $_GET["b"]; parse_str($b); echo "小蓝鲨开始闯关&#xff0c;你能帮助他拿到flag吗?<br>"; if ($a…

AIGC----生成对抗网络(GAN)如何推动AIGC的发展

AIGC: 生成对抗网络(GAN)如何推动AIGC的发展 前言 随着人工智能领域的迅猛发展&#xff0c;AI生成内容&#xff08;AIGC&#xff0c;AI Generated Content&#xff09;正成为创意产业和技术领域的重要组成部分。在AIGC的核心技术中&#xff0c;生成对抗网络&#xff08;GAN&am…

删除k8s 或者docker运行失败的脚本

vi delete_exited_containers.sh#!/bin/bash# 列出所有停止的容器并存储到数组 list_exited_containers() {echo -e "\nStopped containers:"containers()# 获取停止的容器信息并存入数组while IFS read -r line; docontainers("$line")done < <(do…

如何在MindMaster思维导图中制作PPT课件?

思维导图是一种利用色彩、图画、线条等图文并茂的形式&#xff0c;来帮助人们增强知识或者事件的记忆。因此&#xff0c;思维导图也被常用于教育领域&#xff0c;比如&#xff1a;教学课件、读书笔记、时间管理等等。那么&#xff0c;在MindMaster免费思维导图软件中&#xff0…

【unity小技巧】一些unity3D灯光的使用与渲染及性能优化方案

文章目录 天空盒反射配置太阳耀斑眩光烘培光照烘培光照时弹出错误&#xff0c;记得勾选模型下面的选择阴影项目配置光源模型模型shader的问题 全局光照混合光照模式混合照明模式减性照明模式Shadowmask照明模式间接烘焙照明模式 环境光遮罩灯光探针反射探针技术关闭反射探针可以…

Linux :进程间通信之管道

一、进程间通信 1.1 是什么和为什么 1、进程间通信是什么&#xff1f;&#xff1f; ——>两个或多个进程实现数据层面的交互&#xff0c;但是由于进程独立性的存在&#xff0c;导致通信的成本比较高。 2、既然通信成本高&#xff0c;那为什么还要通信呢&#xff1f;&…

“乐鑫组件注册表”简介

当启动一个新的开发项目时&#xff0c;开发者们通常会利用库和驱动程序等现有的代码资源。这种做法不仅节省时间&#xff0c;还简化了项目的维护工作。本文将深入探讨乐鑫组件注册表的概念及其核心理念&#xff0c;旨在指导您高效地使用和贡献组件。 概念解析 ESP-IDF 的架构…