re学习(31)BUUCTF-xx(多层加密)
参考文章:
【BUUCTF逆向 [2019红帽杯]xx】_nb_What_DG的博客-CSDN博客
re学习笔记(26)BUUCTF-re-[2019红帽杯]xx_Forgo7ten的博客-CSDN博客
还有B站 水番正文
IDA64位载入
shift+F12查看字符串
交叉引用找到关键代码
使用findcrypt插件找到加密算法为tea系列,进函数内部查看知道为xxtea
// 代码审计(正向开发经验)
int __cdecl main(int argc, const char **argv, const char **envp)
{__int64 flaglen2; // rbx__int64 flaglen1; // rax__int128 *malloc5; // rax__int64 data; // r11__int128 *malloc7; // r14int v8; // edi__int128 *malloc9; // rsichar tmp; // r10int v11; // edx__int64 v12; // r8unsigned __int64 datalen; // rcx__int64 v14; // rcxunsigned __int64 v15; // raxunsigned __int64 i; // rax__int64 encodeflag; // raxsize_t encodeflaglen; // rsi_BYTE *enflag; // rbx_BYTE *v20; // r9int I; // r11dchar *data1; // r8__int64 n; // rcxchar v24; // al__int64 v25; // r9__int64 v26; // rdx__int64 v27; // raxsize_t Size; // [rsp+20h] [rbp-48h] BYREF__int128 v30; // [rsp+28h] [rbp-40h] BYREFint v31; // [rsp+38h] [rbp-30h]int v32; // [rsp+3Ch] [rbp-2Ch]int flag[4]; // [rsp+40h] [rbp-28h] BYREFint v34; // [rsp+50h] [rbp-18h]*(_OWORD *)flag = 0i64;v34 = 0;sub_1400018C0(std::cin, argv, flag); // 在C++中,std其实就是standard标准的意思。// 例如std::cin就是标准输入,std::cout就是标准输出的意思。flaglen2 = -1i64;flaglen1 = -1i64;do++flaglen1;while ( *((_BYTE *)flag + flaglen1) );if ( flaglen1 != 19 ) // flag 为 19位{sub_140001620((__int64 *)std::cout, (__int64)"error\n");_exit((int)flag);}malloc5 = (__int128 *)operator new(5ui64); // operator new申请内存(operator new后面将进行详细说明,这里理解为C语言中的malloc)data = *(_QWORD *)&Code; // 将Code数据给data,// Code为"qwertyuiopasdfghjklzxcvbnm1234567890"malloc7 = malloc5;v8 = 0;malloc9 = malloc5;do{tmp = *((_BYTE *)malloc9 + (char *)flag - (char *)malloc5);v11 = 0;*(_BYTE *)malloc9 = tmp;v12 = 0i64;datalen = -1i64;do++datalen;while ( *(_BYTE *)(data + datalen) );if ( datalen ){do{if ( tmp == *(_BYTE *)(data + v12) )break;++v11;++v12;}while ( v11 < datalen );}v14 = -1i64;do++v14;while ( *(_BYTE *)(data + v14) );if ( v11 == v14 )_exit(data);malloc9 = (__int128 *)((char *)malloc9 + 1);// 下一位}while ( (char *)malloc9 - (char *)malloc5 < 4 );*((_BYTE *)malloc5 + 4) = 0;do++flaglen2;while ( *((_BYTE *)flag + flaglen2) );v15 = 0i64;v30 = *malloc7;while ( *((_BYTE *)&v30 + v15) ){if ( !*((_BYTE *)&v30 + v15 + 1) ){++v15;break;}if ( !*((_BYTE *)&v30 + v15 + 2) ){v15 += 2i64;break;}if ( !*((_BYTE *)&v30 + v15 + 3) ){v15 += 3i64;break;}v15 += 4i64;if ( v15 >= 0x10 )break;}for ( i = v15 + 1; i < 0x10; ++i )*((_BYTE *)&v30 + i) = 0; // 全部赋值为0encodeflag = (__int64)sub_140001AB0((__int64)flag, flaglen2, (unsigned __int8 *)&v30, &Size);encodeflaglen = Size;enflag = (_BYTE *)encodeflag;v20 = operator new(Size); // v20开辟一块内存区域I = 1;*v20 = enflag[2];data1 = v20 + 1; // v22与v20指向了同一片内存区域v20[1] = *enflag;v20[2] = enflag[3];v20[3] = enflag[1];v20[4] = enflag[6];v20[5] = enflag[4];v20[6] = enflag[7];v20[7] = enflag[5];v20[8] = enflag[10];v20[9] = enflag[8];v20[10] = enflag[11];v20[11] = enflag[9];v20[12] = enflag[14];v20[13] = enflag[12];v20[14] = enflag[15];v20[15] = enflag[13];v20[16] = enflag[18];v20[17] = enflag[16];v20[18] = enflag[19];v20[19] = enflag[17];v20[20] = enflag[22];v20[21] = enflag[20];v20[22] = enflag[23];for ( v20[23] = enflag[21]; I < encodeflaglen; ++data1 )// 异或操作{n = 0i64;if ( I / 3 > 0 ) // I从3开始{v24 = *data1;do{v24 ^= v20[n++]; // v22^v20*data1 = v24;}while ( n < I / 3 ); // I/3是跟前多少位...}++I;}*(_QWORD *)&v30 = 0xC0953A7C6B40BCCEui64;v25 = v20 - (_BYTE *)&v30;*((_QWORD *)&v30 + 1) = 0x3502F79120209BEFi64;v26 = 0i64;v31 = 0xC8021823;v32 = 0xFA5656E7;do{if ( *((_BYTE *)&v30 + v26) != *((_BYTE *)&v30 + v26 + v25) )_exit(v8 * v8);++v8;++v26;}while ( v26 < 24 );v27 = (__int64)sub_140001620((__int64 *)std::cout, (__int64)"You win!");std::ostream::operator<<(v27, sub_1400017F0);return 0;
}
流程为
- 先判断输入的字符串是否都在程序实现存储的数据Code中
- 然后取前四个字符作为xxtea的密钥,(不满位数右端补零)
- 然后对输入的字符串进行加密
- 之后对加密的字符串打乱顺序
- 之后异或操作
- 再与存储的数据进行比对
其中第6部存储的数据为
v30,v30+1,v31,v32在栈上存放的位置相连。小端序存放,需将其反过来写。
开始写脚本:
一.逆异或 二.正序
data0 = "CEBC406B7C3A95C0EF9B202091F70235231802C8E75656FA"#为提取出来的v29,v29+1,v30,v31
data = []
for i in range(0,len(data0),2):data.append(int(data0[i]+data0[i+1],16))#每两位为整体,将16进制转换为10进制
print(data)
for i in range(len(data)-1,-1,-1):for j in range(i//3):data[i] ^= data[j]#1.进行的异或操作
print(data)
biao = [2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]#置换表
shuju = [1]*24
for i in range(24):shuju[biao[i]] = data[i]#2.将其按照一定顺序置换
print(shuju)
print(len(shuju))
三.得到加密数据 密钥key xxtea解密
因为用户输入的为19位字符,也就是38位十六进制字符串,而上面生成了40位,所以要去掉最后两位,也就是去掉13。
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "encode.h"
int main()
{int i,j,data[] = { 188, 165, 206, 64, 244, 178, 178, 231, 169, 18, 157, 18, 174, 16, 200, 91, 61, 215, 6, 29, 220, 112, 248, 220 };for (i = 1; i <= 6; i++)//3.导出加密的数据,将其转换为十六进制并用小端序来表示{printf("0x");for (j = i * 4 - 1; j > (i - 1) * 4 - 1; j--)printf("%x", data[j]);printf(",");}printf("\n0x");int key[] = { 'f','l','a','g' };//导出密钥,将其转换为十六进制并用小端序来表示for (i = 3; i >= 0; i--)printf("%x", key[i]);printf(",");for (i = 0; i < 3; i++)//密钥为4个32位的数,1个字符4bit,4个字符为32bit,还差3个32bit的数printf("0x0,");
}
图片展示
#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) /* Coding Part */{rounds = 6 + 52/n;sum = 0;z = v[n-1];do{sum += DELTA;e = (sum >> 2) & 3;for (p=0; p<n-1; p++){y = v[p+1];z = v[p] += MX;}y = v[0];z = v[n-1] += MX;}while (--rounds);}else if (n < -1) /* Decoding Part */{n = -n;rounds = 6 + 52/n;sum = rounds*DELTA;y = v[0];do{e = (sum >> 2) & 3;for (p=n-1; p>0; p--){z = v[p-1];y = v[p] -= MX;}z = v[n-1];y = v[0] -= MX;sum -= DELTA;}while (--rounds);}
}int main()
{uint32_t v[6]= {0x40cea5bc,0xe7b2b2f4,0x129d12a9,0x5bc810ae,0x1d06d73d,0xdcf870dc};uint32_t const k[4]= {0x67616c66,0,0,0};int n= 6; //n的绝对值表示v的长度,取正表示加密,取负表示解密// v为要加密的数据是两个32位无符号整数// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位//printf("加密前原始数据:%u %u\n",v[0],v[1]);//btea(v, n, k);//printf("加密后的数据:%u %u\n",v[0],v[1]);btea(v, -n, k);for (int i = 0 ; i < 6;i++){printf("%x",v[i]);printf(" ");}return 0;
}m = [0x67616c66,0x5858437b,0x646e615f,0x742b2b5f,0x7d6165]
四.最后将生成的十六进制数用小端序表示
m = [0x67616c66,0x5858437b,0x646e615f,0x742b2b5f,0x7d6165]
flag = ''
for i in m:flag += libnum.n2s(i).decode()[::-1]print(flag)
#flag{CXX_and_++tea}
总结:
1.如果涉及多字节了,应该考虑字节的顺序,比如这个题,就应该将处理的数据都转换为小端序2.这个题的加密步骤有多步(3步:xxtea/乱序/异或)
3.要增强python工具,提高代码能力
相关文章:

re学习(31)BUUCTF-xx(多层加密)
参考文章:【BUUCTF逆向 [2019红帽杯]xx】_nb_What_DG的博客-CSDN博客 re学习笔记(26)BUUCTF-re-[2019红帽杯]xx_Forgo7ten的博客-CSDN博客 还有B站 水番正文 IDA64位载入 shiftF12查看字符串 交叉引用找到关键代码 使用findcrypt插件找到…...
HDFS的小文件影响及解决办法
Hadoop Distributed File System (HDFS) 是用于存储和处理大规模数据的分布式文件系统。然而,HDFS 中的小文件可能会对系统性能和资源利用产生一些影响。下面是小文件对HDFS的影响以及处理方法的一些信息: 影响: 元数据开销: HDFS中的每个文件和目录都有相关的元数据(文件…...
【前端】husky 的使用
husky 是一个优化 git hooks 的 npm 库 Modern native Git hooks made easy 安装和使用 1.安装 npm install husky --save-dev 2. 初始化 npx husky install;官方文档的写法是在 package.json 中初始化,本质上还是执行了 npx husky install 指令 3. 添加…...

Spring系列篇 -- Bean的生命周期
目录 经典面试题目: 一,Bean的生命周期图 二,关于Bean的生命周期流程介绍: 三,Bean的单例与多例模式 总结: 前言:今天小编给大家带来的是关于Spring系列篇中的Bean的生命周期讲解。在了解B…...

分类预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元多输入分类预测
分类预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元多输入分类预测 目录 分类预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.Matlab实现BO-BiGRU贝叶斯优化双向门控循环单元多特征分…...

Linux权限系列--给普通用户添加某个命令的sudo权限
原文网址:Linux权限系列--给普通用户添加某个命令的sudo权限_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Linux系统如何给普通用户添加某个命令的sudo权限。 使用场景 普通开发者可能需要sudo的命令: apt-get(经常要安装软件&#x…...

11-数据结构-栈和队列的应用(C语言)
栈和队列的应用 目录 栈和队列的应用 一、括号匹配(栈) 二、表达式的各种转换 (1)中缀转后缀(手工) (2)后缀转中缀表达式(手工) (3)中缀转后缀(栈) (4)中缀转后缀(树) (5)后缀表达式求值 (6)中缀表达式求值(栈…...

uni-app自定义多环境配置,动态修改appid
背景 在企业级项目开发中,一般都会分为开发、测试、预发布、生产等多个环境,在工程化中使用不同的打包命令改变环境变量解决不同环境各种变量需要手动修改的问题,比如接口请求地址,不同环境的请求路径前缀都是不同的。在使用uni-…...

04 - 分离头指针情况、理解HEAD和branch
查看所有文章链接:(更新中)GIT常用场景- 目录 文章目录 1. 分离头指针2. HEAD和branch2.1 branch的一些操作2.2 HEAD 1. 分离头指针 分离头指针detached HEAD是一种HEAD指针指向了某一个具体的 commit id,而不是分支的情况。 切换…...

C#__基本特性和使用
// 特性(attribute): // 一种允许我们向程序集添加元数据的语言结构 // 用于保存程序结构信息的某种特殊类型的类 // 类似“批注”,用于解释说明 #define IsShowMessage // 宏定义,在开头定义࿰…...
mysql(3)
分库分表 分库:将数据库中的数据分散到不同数据库上,可以垂直分库和水平分库。 1.垂直分库:把单一的数据按照业务进行划分,不同的业务使用不同的数据库,进而将一个数据库的压力分散到多个数据库。 2.水平分库&#…...
阿里巴巴常用的12个后端开发工具
1 阿尔萨斯Java在线诊断工具 Arthas是一款用于Java应用程序的在线诊断工具,由阿里巴巴于2018年9月开源。 典型场景: 您不知道从中加载类的特定JAR包。 您想弄清楚为什么您的系统会抛出各种与类相关的异常。 您不知道为什么修改后的代码无法执行。您不…...

php base64转图片保存本地
调用函数 public function base64(){$img $this->request->param(img);$img data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAkACQAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy…...

unity物体移动至指定位置
物体坐标与物体移动 世界坐标与局部坐标之间的转换物体移动至指定位置需求思路注意 世界坐标与局部坐标之间的转换 在Unity中,物体的坐标分为局部坐标和世界坐标。 局部坐标是相对于物体的父对象的坐标系,而世界坐标是相对于场景的整体坐标系。 使用tr…...

详解C#-static void Main(string[] args)
目录 简介: 举例: 输出结果:编辑 总结: 简介: 在C#中static void Main(string[] args)这个句话有什么作用,分别代表什么意思!! 这句话是入口函数的声明,指定了C#程序的入口点,并定义了一个名为”Mai…...

中大许少辉博士《乡村振兴战略下传统村落文化旅游设计》中国建筑工业出版社八一付梓。
中大许少辉博士《乡村振兴战略下传统村落文化旅游设计》中国建筑工业出版社八一付梓。...

Matplotlib数据可视化(五)
目录 1.绘制折线图 2.绘制散点图 3.绘制直方图 4.绘制饼图 5.绘制箱线图 1.绘制折线图 import matplotlib.pyplot as plt import numpy as np %matplotlib inline x np.arange(9) y np.sin(x) z np.cos(x) # marker数据点样式,linewidth线宽,li…...
Python爬虫——requests_post请求
import requests import jsonurl https://fanyi.baidu.com/sugheaders {User-Agent: ,Cookie: }data {kw: hello }response requests.post(url, data, headersheaders)content response.textobj json.loads(content.encode(utf-8)) print(obj)总结: post请求…...

excel 下载方法封装
1.首先需要拿到后端返回的URL下载地址 2.写个下载方法 // url 接口返回的下载地址。例如:https://cancer-research.oss-cn-beijing.aliyuncs.com/yuance-platform-permission/校内共享数据导入模板.xlsx // name 文件名称 例如: 校内共享数据导入模板 /…...
按日,周,月,季,年统计;获取对应的时间段
按日,周,月,季,年统计;获取对应的时间段 1.周实体类:WeekEntity.java package com.test.common.entity;import java.time.LocalDate;public class WeekEntity {private String day;/*** 开始日期**/privat…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...

Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
游戏开发中常见的战斗数值英文缩写对照表
游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...