当前位置: 首页 > news >正文

[GUET-CTF2019]encrypt

我自己大致分析的是输入flag然后先 RC4加密再 base64加密,解了一下发现不对。

那就只能仔细分析了,看有没有魔改

嗯,可以动调试试,嗯就是要找其 key 的值 :0x10,0x20,0x30,0x30,0x20,0x10,0x40

aaaaaaaaaa--->dd426c16da58a81d4e1d

还不知道藏哪去了,找到了,还要加一个偏移的

好像真不是 RC4 啊,但看wp:说就是的

嗯,不好分析,一种做法就是直接调试,得到关键的变量值

第一个就是得到 v9 的值

记录每次 edx 的值

最后就是这个类似base64d了

_DWORD *__fastcall sub_4008FA(__int64 a1, int a2, const char *a3, _DWORD *a4)
{int v4; // eaxint v5; // eaxunsigned __int8 v6; // alint v7; // eaxunsigned __int8 v8; // alint v9; // eaxint v10; // edx_DWORD *result; // raxchar v13; // [rsp+2Dh] [rbp-13h]unsigned __int8 v14; // [rsp+2Eh] [rbp-12h]unsigned __int8 v15; // [rsp+2Fh] [rbp-11h]int v16; // [rsp+30h] [rbp-10h]int v17; // [rsp+34h] [rbp-Ch]v16 = 0;v17 = 0;while ( v17 < a2 ){v4 = v17++;v13 = *(_BYTE *)(v4 + a1);if ( v17 >= a2 ){v6 = 0;}else{v5 = v17++;v6 = *(_BYTE *)(v5 + a1);}v14 = v6;if ( v17 >= a2 ){v8 = 0;}else{v7 = v17++;v8 = *(_BYTE *)(v7 + a1);}v15 = v8;a3[v16] = ((v13 >> 2) & 0x3F) + 61;a3[v16 + 1] = ((((int)v14 >> 4) | (16 * v13)) & 0x3F) + '=';a3[v16 + 2] = ((((int)v8 >> 6) | (4 * v14)) & 0x3F) + '=';v9 = v16 + 3;v16 += 4;a3[v9] = (v15 & 0x3F) + '=';}if ( a2 % 3 == 1 ){a3[--v16] = 61;}else if ( a2 % 3 != 2 ){goto LABEL_15;}a3[v16 - 1] = 61;
LABEL_15:v10 = strlen(a3);result = a4;*a4 = v10;return result;
}

下面这是标准base64 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";void base64_encode(const unsigned char *input, int length, char *output) {int i, j;for (i = 0, j = 0; i < length;) {uint32_t octet_a = i < length ? input[i++] : 0;uint32_t octet_b = i < length ? input[i++] : 0;uint32_t octet_c = i < length ? input[i++] : 0;uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;output[j++] = base64_chars[(triple >> 3 * 6) & 0x3F];output[j++] = base64_chars[(triple >> 2 * 6) & 0x3F];output[j++] = base64_chars[(triple >> 1 * 6) & 0x3F];output[j++] = base64_chars[(triple >> 0 * 6) & 0x3F];}for (int k = 0; k < mod_table[length % 3]; k++)output[*output_length - 1 - k] = '=';output[j] = '\0';
}int main() {const char *input = "Hello, World!";char output[32]; // ensure it's large enoughbase64_encode((const unsigned char*)input, strlen(input), output);printf("Base64 Encoded: %s\n", output);return 0;
}

 自己简化一下再分析一下

v16 = 0;v17 = 0;while ( v17 < a2 ){v13=a1[v17++];if(v17>=a2){v6=0;v8=0;
} else {v6=a1[v17++];v8=a1[v17++];
}
v14=v6;
v15=v8;
a3[v16]=((v13>>2)& 0x3f)+61;
a3[v16+1]=((((int)v14 >> 4) | (16 * v13)) & 0x3F) + '=';
a3[v16 + 2] = ((((int)v8 >> 6) | (4 * v14)) & 0x3F) + '=';
v16+=4;
a3[v16+3]=(v15&0x3f)+61;
}
if (a2%3==1){a3[v16]=61;
}else if (a2%3!=2){
v10 = strlen(a3);result = a4;*a4 = v10;return result;
}a3[v16 - 1] = 61;
//别人更好看
v16 = 0;v17 = 0;while (v17 < a2){v13 = a1[v17++];v14 = a1[v17++];v15 = a1[v17++];//取三个字符a3[v16]     = ((          v13 >> 2            ) & 0x3F) + 61;a3[v16 + 1] = ((   (v14 >> 4) | ( v13 << 4)   ) & 0x3F) + 61;a3[v16 + 2] = ((   (v15 >> 6) | ( v14 << 2)   ) & 0x3F) + 61;a3[v16 + 3] =            (v15 & 0x3F)                   + 61;v16 += 4;}//等号填充if (a2 % 3 == 1){a3[--v16] = 61;}else if (a2 % 3 != 2){goto LABEL_15;}a3[v16 - 1] = 61;
LABEL_15:v10 = strlen(a3);result = a4;*a4 = v10;return result;
}
data=[0x5a, 0x60, 0x54, 0x7A, 0x7A, 0x54, 0x72, 0x44,0x7C, 0x66, 0x51, 0x50, 0x5B, 0x5F, 0x56, 0x56,0x4C, 0x7C, 0x79, 0x6E, 0x65, 0x55, 0x52, 0x79,0x55, 0x6D, 0x46, 0x6B, 0x6C, 0x56, 0x4A, 0x67,0x4C, 0x61, 0x73, 0x4A, 0x72, 0x6F, 0x5A, 0x70,0x48, 0x52, 0x78, 0x49, 0x55, 0x6C, 0x48, 0x5C,0x76, 0x5A, 0x45, 0x3D]
flag=''
for i in range(0,len(data),4):flag+=chr((((data[i]-0x3D)&0x3F)<<2)|(((data[i+1]-0x3D)&0x30)>>4))flag+=chr((((data[i+1]-0x3D)&0x0F)<<4)|(((data[i+2]-0x3D)&0x3C)>>2))flag+=chr(((data[i+3]-0x3D)&0x3F)|((data[i+2]-0x3D)&0x03)<<6)
j=0
l=[0x10,0x59,0x9C,0x92,0x06,0x22,0xCF,0xA5,0x72,0x1E,0x45,0x6A,0x06,0xCB,0x08,0xC3,0xE4,0x49,0x5A,0x63,0x0C,0xDF,0xF6,0x5F,0x08,0x28,0xBD,0xE2,0x10,0x15,0x1F,0x6E,0xAA,0x5A,0xCA,0xEC,0x80,0xAF,0x9B,0x16,0xBB,0x3D,0x13,0x2F,0x6A,0xA4,0xC7,0x2E,0xBC,0x4B,0x60,0x9A,0xAF,0xE9,0xCE,0xDA,0x67,0x39,0xBA,0x3B,0x85,0xEB,0xD2,0x6B,0xAB,0x06,0x6B,0x10,0x57,0x2C,0x88,0x70,0xF7,0x4F,0xAA,0x7F,0x12,0x47,0xD6,0xDE,0x74,0xB2,0x1D,0xA4,0xD7,0x76,0x9A,0xE0]
a=list(flag)
flag=''
for i in a:flag+=chr(ord(a[j])^l[j])j+=1
print(flag)

嗯,动静结合,这题感觉很妙啊!

[GUET-CTF2019]encrypt-CSDN博客

buuctf [GUET-CTF2019]encrypt纯静态做法_buuctf encrypt 3-CSDN博客

相关文章:

  • Windows11提示“该文件没有与之关联的程序来执行该操作,请安装应用,若已经安装应用,请在‘默认应用设置’页面中创建关联。
  • 多线程案例(线程池)
  • TOGAF的核心-企业四大架构领域简介
  • Stanford斯坦福 CS 224R: 深度强化学习 (5)
  • Python-图片旋转360,保存对应图片
  • 代码随想录算法训练营第三十四天|860.柠檬水找零、406.根据身高重建队列、452. 用最少数量的箭引爆气球
  • Qt5 互动地图,实现无人机地面站效果
  • 指纹识别概念解析
  • 【Linux】$()中的内容与不加$()时有什么区别
  • 请解释Java Web中的Filter过滤器的作用和常见应用场景。什么是Java Web中的Servlet API?请列举其核心接口和类。
  • 中间件-------RabbitMQ
  • 浅谈nginx配置文件
  • Hadoop运行wordcount实例任务卡在job running的多种情况及解决方法
  • 前端开发攻略---用Vue实现无限滚动的几种方法
  • 10款免费黑科技软件,强烈推荐!
  • 自己简单写的 事件订阅机制
  • [数据结构]链表的实现在PHP中
  • 2017届校招提前批面试回顾
  • 5、React组件事件详解
  • css属性的继承、初识值、计算值、当前值、应用值
  • java中具有继承关系的类及其对象初始化顺序
  • Laravel Mix运行时关于es2015报错解决方案
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Shell编程
  • 创建一种深思熟虑的文化
  • 对超线程几个不同角度的解释
  • 规范化安全开发 KOA 手脚架
  • 基于游标的分页接口实现
  • 前端攻城师
  • 译米田引理
  • 从如何停掉 Promise 链说起
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • ​业务双活的数据切换思路设计(下)
  • #pragma预处理命令
  • #QT 笔记一
  • #面试系列-腾讯后端一面
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (Oracle)SQL优化技巧(一):分页查询
  • (二) 初入MySQL 【数据库管理】
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .Net Core缓存组件(MemoryCache)源码解析
  • .net/c# memcached 获取所有缓存键(keys)
  • .Net--CLS,CTS,CLI,BCL,FCL
  • .NET开源、简单、实用的数据库文档生成工具
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [5] CUDA线程调用与存储器架构
  • [BZOJ3211]:花神游历各国(小清新线段树)
  • [C++] 模拟实现list(二)
  • [CareerCup][Google Interview] 实现一个具有get_min的Queue
  • [Cesium学习]
  • [ES-5.6.12] x-pack ssl