[HUBUCTF 2022 新生赛]simple_RE
[HUBUCTF 2022 新生赛]simple_RE
查壳,64位

找main函数,F5查看伪代码,简单分析一下

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+24h] [rbp-44h] BYREF
void *Buf1; // [rsp+28h] [rbp-40h] BYREF
char v6[56]; // [rsp+30h] [rbp-38h] BYREF sub_401770(argc, argv, envp);
printf("please input the flag:");
scanf("%s", v6); // v6是flag
Buf1 = 0i64; // 初始化Buf1
sub_401570(v6, &Buf1, &v4); // v6进行base64编码,但是不是根据A-Z,...,而是根据这串字符编码qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD
if ( !memcmp(Buf1, a5mc58bphliax7j, v4) ) // 对这串字符串"5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="进行微改变的base64解码,即得flag
printf("\nsuccess!");
else
printf("\nfailed!");
if ( Buf1 )
free(Buf1);
return 0;
}
v6是flag,经过sub_401570函数加密,得到a5mc58bphliax7j对应的加密后的值,即加密后的flag值
这里的重点就是sub_401570函数,我们需要了解经过怎么样的加密,接下来我们点进去看看

sub_401570函数
__int64 __fastcall sub_401570(const char *a1, _QWORD *a2, int *a3)
{
int v6; // r15d
int v7; // r12d
int v8; // r13d
__int64 v9; // r14
_BYTE *v10; // rax
_BYTE *v11; // r9
__int64 v12; // r8
char v13; // cl
char v14; // r11
char v15; // r10
__int64 result; // rax v6 = strlen(a1);
v7 = v6 % 3;
if ( v6 % 3 )
{
v8 = 4 * (v6 / 3) + 4;
v9 = v8;
v10 = malloc(v8 + 1i64);
v10[v8] = 0;
if ( v6 <= 0 )
goto LABEL_5;
}
else
{
v8 = 4 * (v6 / 3);
v9 = v8;
v10 = malloc(v8 + 1i64);
v10[v8] = 0;
if ( v6 <= 0 )
goto LABEL_8;
}
v11 = v10;
v12 = 0i64;
do
{
v11 += 4;
v13 = a1[v12];
*(v11 - 4) = aQvejafhmuyjbac[v13 >> 2];
v14 = a1[v12 + 1];
*(v11 - 3) = aQvejafhmuyjbac[(v14 >> 4) | (16 * v13) & 0x30];
v15 = a1[v12 + 2];
v12 += 3i64;
*(v11 - 2) = aQvejafhmuyjbac[(v15 >> 6) | (4 * v14) & 0x3C];
*(v11 - 1) = aQvejafhmuyjbac[v15 & 0x3F];
}
while ( v6 > (int)v12 );
LABEL_5:
if ( v7 == 1 )
{
v10[v9 - 2] = 61;
v10[v9 - 1] = 61;
}
else if ( v7 == 2 )
{
v10[v9 - 1] = 61;
}
LABEL_8:
*a2 = v10;
result = 0i64;
*a3 = v8;
return result;
}
看不懂不要紧,为了这个,我专门用一天时间消化base64编码与解码的原理,链接如下:base64详解 - Zer0o - 博客园 (cnblogs.com)
看完,就能对base64原理了解的八九不离十了
这段代码一看移位运算,或运算,与运算,与base64编码一样,只不过base64是根据ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/编码,而这里修改为aQvejafhmuyjbac对应的字符串

双击进入,知道这个base64是根据这串字符串编码的qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD,而不是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

知道原理了,返回main函数

简单捋一下,就是将flag进行变异的base64编码,编码结果为a5mc58bphliax7j对应的数据,即5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==

写出源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h> char base64CharsArr[] = "qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD"; void base64decode(char str[]) {
int length = strlen(str);
int padding = 0; // 计算填充字符数量
if (str[length - 1] == '=') {
padding++;
if (str[length - 2] == '=')
padding++;
} // 计算解码后的字符数量
int decodedLength = (length * 3) / 4 - padding; // 分配存储解码结果的内存
char* decodedStr = (char*)malloc(decodedLength + 1); int outIndex = 0;
for (int i = 0; i < length; i += 4) {
char char1 = -1, char2 = -1, char3 = -1, char4 = -1; // 查找每个字符在Base64字符集中的索引
for (int j = 0; j < 64; j++) {
if (base64CharsArr[j] == str[i]) {
char1 = j;
break;
}
} for (int j = 0; j < 64; j++) {
if (base64CharsArr[j] == str[i + 1]) {
char2 = j;
break;
}
} for (int j = 0; j < 64; j++) {
if (base64CharsArr[j] == str[i + 2]) {
char3 = j;
break;
}
} for (int j = 0; j < 64; j++) {
if (base64CharsArr[j] == str[i + 3]) {
char4 = j;
break;
}
} // 解码并存储结果
decodedStr[outIndex++] = (char1 << 2) | ((char2 & 0x30) >> 4);
if (char3 != -1)
decodedStr[outIndex++] = ((char2 & 0xf) << 4) | ((char3 & 0x3c) >> 2);
if (char4 != -1)
decodedStr[outIndex++] = ((char3 & 0x3) << 6) | char4;
} // 添加字符串结束符
decodedStr[decodedLength] = '\0'; printf("Decoded string: %s\n", decodedStr); // 释放内存
free(decodedStr);
} int main() {
char str[100]="5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="; // Example base64 encoded string
base64decode(str);
return 0;
}

flag:NSSCTF{a8d4347722800e72e34e1aba3fe914ae}
[HUBUCTF 2022 新生赛]simple_RE的更多相关文章
- SCNU ACM 2016新生赛初赛 解题报告
新生初赛题目.解题思路.参考代码一览 1001. 无聊的日常 Problem Description 两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他 ...
- SCNU 2015ACM新生赛决赛【F. Oyk闯机关】解题报告
题目大意:一个$N$$\times$$N$的阵列,每个格子有$X_{ij}$个调和之音,若每次只能选择走右边或下边,从左上角出发走到右下角,问最多能收集到多少个调和之音? ...
- Codeforces 801 A.Vicious Keyboard & Jxnu Group Programming Ladder Tournament 2017江西师大新生赛 L1-2.叶神的字符串
A. Vicious Keyboard time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- [ACTF2020 新生赛]BackupFile && [ACTF2020 新生赛]Upload &&[GYCTF2020]Blacklist
[ACTF2020 新生赛]BackupFile 尝试找到源代码,加上题目是备份文件,猜测备份文件里面有网站的源代码,御剑扫描一下,就扫到index.php 访问index.php.bak 下载源代码 ...
- [BUUCTF]REVERSE——[ACTF新生赛2020]Oruga
[ACTF新生赛2020]Oruga 附件 步骤: 例行检查,64位程序,无壳 64位ida载入,检索字符串,根据提示来到关键函数 14行~18行就是让字符串的前5位是 actf{ ,sub_78A( ...
- [BUUCTF]REVERSE——[ACTF新生赛2020]usualCrypt
[ACTF新生赛2020]usualCrypt 附件 步骤: 例行检查,无壳,32位程序 32位ida载入,直接看main函数 逻辑很简单,一开始让我们输入一个字符串,然后该字符串经过sub_4010 ...
- [BUUCTF]REVERSE——[ACTF新生赛2020]rome
[ACTF新生赛2020]rome 附件 步骤 无壳,32位程序 32位ida载入,根据提示字符串"You are correct!",找到关键函数func v15 = 'Q'; ...
- [BUUCTF]REVERSE——[ACTF新生赛2020]easyre
[ACTF新生赛2020]easyre 附件 步骤 查壳,32位程序,upx壳儿 脱完壳儿,扔进ida 分析 一开始给我们定义了一个数组, v4=[42,70,39,34,78,44,34,40,73 ...
- GDOU-CTF-2023新生赛Pwn题解与反思
第一次参加CTF新生赛总结与反思 因为昨天学校那边要进行天梯模拟赛,所以被拉过去了.16点30分结束,就跑回来宿舍开始写.第一题和第二题一下子getshell,不用30分钟,可能我没想那么多,对比网上 ...
- SCNU ACM 2016新生赛决赛 解题报告
新生初赛题目.解题思路.参考代码一览 A. 拒绝虐狗 Problem Description CZJ 去排队打饭的时候看到前面有几对情侣秀恩爱,作为单身狗的 CZJ 表示很难受. 现在给出一个字符串代 ...
随机推荐
- devops|中小公司不要做研发效能度量
我特别反感那些不顾公司现状一上来就想要做研发效能度量的人,尤其是想把研发效能度量当成锤子四处去敲打螺丝钉的人. 没几个人的小公司上来就做研发效能度量,就如同普通人一上来直接问媒婆怎么能娶到迪丽热巴.解 ...
- 麻了,不要再动不动就BeanUtil.copyProperties!!!
前言 最近项目上要求升级一个工具包hutool的版本,以解决安全漏洞问题,这不升级还好,一升级反而捅出了更大的篓子,究竟是怎么回事呢? 事件回顾 我们项目原先使用的hutool版本是5.7.2,在代码 ...
- 【Vue2.x源码系列07】监听器watch原理
上一章 Vue2计算属性原理,我们介绍了计算属性是如何实现的?计算属性缓存原理?以及洋葱模型是如何应用的? 本章目标 监听器是如何实现的? 监听器选项 - immediate.deep 内部实现 初始 ...
- Java线程中断机制
在阅读AQS源码以及juc包很多基于AQS的应用源码过程中,会遇到很多interrupted相关的方法,这里复习一下java线程中断相关. 要点:使用interrupt()中断一个线程,该方法只是标记 ...
- React 富文本编辑 braft-editor
推荐一种react-富文本编辑器,braft-editor braft-editor的github:https://github.com/margox/braft-editor braft-edito ...
- Prism Sample 7 Module xaml
这一节使用xaml标记甚为不解. 本节注册module 的方式同directory一节很类似.在那一节中,用工厂方法创建一模块目录: protected override IModuleCatalog ...
- 【漏洞分析】ReflectionToken BEVO代币攻击事件分析
前言 BEVO代币是一种Reflection Token(反射型代币),并且拥有通缩的特性.关于Reflection Token更为详细的说明可参考这篇文章.然后目前浏览到的很多分析报告没有指出其漏洞 ...
- workerman、websocket简单聊天功能从0到1实现
一.workerman安装,测试环境为linux 1.在网站根目录,用命令行安装,要是出现root权限提示,输入y回车就行,或者新建一个用户再进入安装 Linux系统可以使用以下脚本测试本机PHP环境 ...
- PaddlePaddle 自动求导
自动求导 在 PaddlePaddle 中使用自动求导来计算导数. 要求:$ f(x)=\sin{x} $,绘制 \(f(x)\) 和 \(\dfrac{\mathrm{d}f(x)}{\mathrm ...
- 2022-02-16:将数组分割成和相等的子数组。 给定一个有 n 个整数的数组,你需要找到满足以下条件的三元组 (i, j, k) : 0 < i, i + 1 < j, j + 1 < k < n
2022-02-16:将数组分割成和相等的子数组. 给定一个有 n 个整数的数组,你需要找到满足以下条件的三元组 (i, j, k) : 0 < i, i + 1 < j, j + 1 & ...