逆向解密

base64

基本概念:

base64根据百度的查询,定义如下:Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。//64个字符为:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=

基本原理:

即把一个3字节的数据转换为4字节的数据存储-----以二进制的形式进行操作。
假设现在要对"abc"这串字符串进行base64加密,首先判断该数据是否为 3的倍数的 字节大小(其中一个字符1字节,一个字节可以用8个二进制表示)该数据确定为3字节大小的倍数后根据ascii码对应的二进制表示出来

 将二进制每6位为一组,然后高位补00,形成8位一组然后将其二进制对应的base64表中的值去对应相应的base64码最后就能得到base64加密的字符串”YWJj"

若加密的数据不足3的倍数的字节的大小,那么就在其 编码过程 中补\x00,补足其位数,补了几个\x00,最后就加上几个'='现要加密字符'1'//其ascii表对应的二进制为0011 0001(49)操作如下和正常情况加密相似

base64表如下:

​ 摘自百度

C语言实现

#include<stdio.h>
#include<string.h>
#define MAX 100000
char base64[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="};//base64表
char decode(char flag[]);
int main(){char text[MAX];scanf("%s",&text);int i=0;int j=0;long len=strlen(text);char flag[MAX];int v4=len%3;switch(v4){//字符串是3的倍数长度的情况 case 0:{len=(strlen(text)/3)*4;for(i=0;i<len;){flag[i]=base64[text[j]>>2];//取第一位元素text[0]的前6位 flag[i+1]=base64[ ( ( text[j] & 0x3 ) << 4 ) | ( ( text[j+1] >> 4 ) ) ];//取第一位元素text[0]的后两位和第二元素text[1]的前4位 flag[i+2]=base64[((text[j+1]&0xf)<<2)|((text[j+2]&0xc0)>>6)];//取text[1]的后4位和text[2]的前2位 flag[i+3]=base64[text[j+2]&0x3f];//取text[2]的后六位 i=i+4;j=j+3;}break;}//长度比3的倍数多一的情况 case 1:{len=(strlen(text)/3)*4;//先对前面3的倍数的长度经行正常规则编码 for(i=0;i<len;){flag[i]=base64[text[j]>>2];flag[i+1]=base64[ ( ( text[j] & 3 ) << 4 ) | ( ( text[j+1] >> 4 ) ) ]; flag[i+2]=base64[((text[j+1]&0xf)<<2)|((text[j+2]&0xc0)>>6)];flag[i+3]=base64[text[j+2]&0x3f];i=i+4;j=j+3;}//再对多出来的字符以在二进制末尾补充/x00的形式进行编码,末尾填写多少个/x00就在编码末尾添加几个‘=’ flag[i]=base64[text[j]>>2];flag[i+1]=base64[ ( ( text[j] & 3 ) << 4 ) | ( ( text[j+1] >> 4 ) ) ]; flag[i+2]=base64[strlen(base64)-1];// '='flag[i+3]=base64[strlen(base64)-1];// '='break;}//长度比3的倍数多2的情况 //编码规则和多1的一样 case 2:{len=(strlen(text)/3)*4;for(i=0;i<len;){flag[i]=base64[text[j]>>2];flag[i+1]=base64[ ( ( text[j] & 3 ) << 4 ) | ( ( text[j+1] >> 4 ) ) ]; flag[i+2]=base64[((text[j+1]&0xf)<<2)|((text[j+2]&0xc0)>>6)];flag[i+3]=base64[text[j+2]&0x3f];i=i+4;j=j+3;}flag[i]=base64[text[j]>>2];flag[i+1]=base64[ ( ( text[j] & 3 ) << 4 ) | ( ( text[j+1] >> 4 ) ) ]; flag[i+2]=base64[((text[j+1]&0xf)<<2)|((text[j+2]&0xc0)>>6)];flag[i+3]=base64[strlen(base64)-1];// '='break;}}printf("%s\n",flag);decode(flag);//base64的解码 return 0;
}
char decode(char flag[]){char base64[MAX];base64['A']=0;base64['B']=1;base64['C']=2;base64['D']=3;base64['E']=4;base64['F']=5;base64['G']=6;base64['H']=7;base64['I']=8;base64['J']=9;base64['K']=10;base64['L']=11;base64['M']=12;base64['N']=13;base64['O']=14;base64['P']=15;base64['Q']=16;base64['R']=17;base64['S']=18;base64['T']=19;base64['U']=20;base64['V']=21;base64['W']=22;base64['X']=23;base64['Y']=24;base64['Z']=25;base64['a']=26;base64['b']=27;base64['c']=28;base64['d']=29;base64['e']=30;base64['f']=31;base64['g']=32;base64['h']=33;base64['i']=34;base64['j']=35;base64['k']=36;base64['l']=37;base64['m']=38;base64['n']=39;base64['o']=40;base64['p']=41;base64['q']=42;base64['r']=43;base64['s']=44;base64['t']=45;base64['u']=46;base64['v']=47;base64['w']=48;base64['x']=49;base64['y']=50;base64['z']=51;base64['0']=52;base64['1']=53;base64['2']=54;base64['3']=55;base64['4']=56;base64['5']=57;base64['6']=58;base64['7']=59;base64['8']=60;base64['9']=61;base64['+']=62;base64['/']=63;//建立base64表 ,后续根据base64表对应的十进制进行移位操作,到达解码的目的 int i=0;int j=0;int len=strlen(flag);//判断原始明文长度 if(flag[len-1]=='='&&flag[len-2]!='=')len=len/4*3-1;else if(flag[len-2]=='=')len=len/4*3-2;elselen=len/4*3;
 char text[len];for(i=0;i<len;){text[i]=(base64[flag[j]]<<2)|((base64[flag[j+1]]<<2)&0x60)>>6;//取flag[0]的后六位和flag[1]的前2位 text[i+1]=(base64[flag[j+1]]<<4)|(base64[flag[j+2]]<<2)>>4;//取flag[1]的后4位和flag[2]的中间4位text[i+2]=(base64[flag[j+2]]<<6)|base64[flag[j+3]]&0x3f; //取flag[2]的后2位和flag{3]的后6位 i=i+3;j=j+4;}printf("%s",text); return *text;
}

关于base64的题

BUUCTF-reverse-3

IDA32打开进行分析

没找到main函数,然后打开string window界面,找到”right flag!“字符串跟进去,对该部分函数进行分析

int sub_4156E0()
{int v0; // eax@6int v1; // eax@6size_t v2; // eax@9char v4; // [sp+0h] [bp-188h]@6char v5; // [sp+Ch] [bp-17Ch]@1size_t v6; // [sp+10h] [bp-178h]@3size_t j; // [sp+DCh] [bp-ACh]@6size_t i; // [sp+E8h] [bp-A0h]@1char Dest[108]; // [sp+F4h] [bp-94h]@5char Str; // [sp+160h] [bp-28h]@6char v11; // [sp+17Ch] [bp-Ch]@6unsigned int v12; // [sp+184h] [bp-4h]@1int savedregs; // [sp+188h] [bp+0h]@1memset(&v5, 0xCCu, 0x17Cu);v12 = (unsigned int)&savedregs ^ __security_cookie;for ( i = 0; (signed int)i < 100; ++i ){v6 = i;if ( i >= 0x64 )sub_411154();Dest[v6] = 0;}sub_41132F("please enter the flag:", v4);sub_411375("%20s", &Str);                     // Str字符串就是flagv0 = j_strlen(&Str);                          // V0表示flag的长度v1 = sub_4110BE((int)&Str, v0, (int)&v11);    // 调用函数sub_4110BE进行加密str操作,同时加密后的代码返回给V1strncpy(Dest, (const char *)v1, 0x28u);       // 将加密后的flag也就是v1复制到Dest里面sub_411127();i = j_strlen(Dest);for ( j = 0; (signed int)j < (signed int)i; ++j )// 对加密后的flag也就是Dest中的每个元素加j操作Dest[j] += j;                               // Dest[j]=Dest[j]+j;v2 = j_strlen(Dest);strncmp(Dest, Str2, v2);                      // 比较Dest和Str2,也就是说Str2是最终的加密flagif ( sub_411127() )                           // Str2为e3nifIH9b_C@n@dHsub_41132F("wrong flag!\n", v4);elsesub_41132F("rigth flag!\n", v4);sub_41126C(&savedregs, &dword_415890);sub_411280();return sub_411127();
}

顺着分析下来,其主要的加密部分为

v1 = sub_4110BE((int)&Str, v0, (int)&v11);    // 调用函数sub_4110BE进行加密str操作,同时加密后的代码返回给V1
//和
for ( j = 0; (signed int)j < (signed int)i; ++j )// 对加密后的flag也就是Dest中的每个元素加j操作Dest[j] += j;                               // Dest[j]=Dest[j]+j;

主要跟进sub_4110BE函数

这部分代码就是对传进来的字符串进行base64加密,v4判断本次循环的byte_41A144[0][1][2]是否有3字节的大小然后根据v4的情况进行加密,满足3字节的话,就进第三个判断,正常加密,不满足3字节的就进行补\x00操作,然后加几个\x00就在末尾添几个'='

从该函数跳出后,加密后的字符串被传给了v1,然后又被copy到Dest上,之后又对Dest修改

for ( j = 0; (signed int)j < (signed int)i; ++j )// 对加密后的flag也就是Dest中的每个元素加j操作Dest[j] += j;                               // Dest[j]=Dest[j]+j;

最后Dest只有等于Str2才输出”right flag“

所以就是解题步骤如下:

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){int v4;char a[20]={"e3nifIH9b_C@n@dH"};int i;for(i=0;i<strlen(a);i++){a[i]=a[i]-i;}//memset( &v4,0xCCu,0x100u);printf("%s\n",a);system("pause");return 0;

得原来的base加密后的字符为:e2lfbDB2ZV95b3V9,通过网上的base64解密得flag:

flag{i_l0ve_you}

0x100u);
printf("%s\n",a);
system(“pause”);
return 0;


得原来的base加密后的字符为:==e2lfbDB2ZV95b3V9==,通过网上的base64解密得flag:flag{i_l0ve_you}

2021-9-23 base64学习相关推荐

  1. leetcode刷题记录2:进度64, 2021.10.23

    文章目录 数组的度(题目编号697:[link](https://leetcode-cn.com/problems/degree-of-an-array/)) 二叉搜索树(题目编号700:[link] ...

  2. 2021.3.2-3.8 人工智能行业每周技术动态

    最近,发现很多公众号都在发Transformer的内容. 这是很好的事,说明行业内大家在不断的去尝试,不断的去突破. 之前的一个同事,最近也在一直和我聊,关于他对Transformer在股票分析的一些 ...

  3. 【论文阅读】【逐字翻译】 爱丁堡大学IEEE TPAMI 2021年最新元学习综述 《Meta-Learning in Neural Networks: A Survey》

    开个新坑,长期,不定时更新-一 一+ 原文:Timothy M Hospedales, Antreas Antoniou, Paul Micaelli, Amos J Storkey. Meta-Le ...

  4. 清华大学朱文武团队夺冠AAAI 2021国际深度元学习挑战赛

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要5分钟 Follow小博主,每天更新前沿干货 转自:机器之心 清华大学朱文武教授团队摘得AAAI 2021 国际深度元学习挑战赛(MetaDL ...

  5. C++ 落选,2021 年最想学习的五大编程语言

    作者 | Ashutosh Kumar 译者 | 火火酱,责编 | Carol 出品 | CSDN(ID:CSDNnews) 如今,市面上有非常多编程语言,选起来真是令人眼花缭乱. 选择第一门语言是非 ...

  6. 23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter

    23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter 2016-07-22 (www.cnblogs.com/icmzn) 模式理解 1. Adapter 定义 ...

  7. 电动力学每日一题 2021/10/23 载流板产生的电磁场

    电动力学每日一题 2021/10/23 载流板产生的电磁场 载流板的辐射 载流板的辐射 先验证电荷守恒: ∂ρ∂t=−∇⋅J=−∂∂zJz=0\frac{\partial \rho}{\partial ...

  8. 2021年7月份学习总结,多套WebFuture的系统部署(简易版)

    本文摘录2021年7月份学习总结,创建日期:2021年08月03日 15:37:15,有修改. 在Linux(中标麒麟)+达梦数据库+WebFuture搭配下部署. 「Linux(中标麒麟)+达梦数据 ...

  9. 2021.4.23最新mac11.1 big sur 关于CocoaPods安装和使用

    2021.4.23关于CocoaPods安装和使用 第1部分 CocoaPods 的安装 CocoaPods 是iOS开发必不可少的一个第三方框架的管理工具,和Java的Maven类似,maven也是 ...

  10. 清华大学团队夺冠AAAI 2021国际深度元学习挑战赛

    点上方蓝字计算机视觉联盟获取更多干货 在右上方 ··· 设为星标 ★,与你不见不散 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:机器之心 AI博士笔记系列推荐 周志华<机器学习> ...

最新文章

  1. UE5使用MetaHuman构建超现实的角色
  2. 华人“军火专家”——黄仁勋
  3. Linux下截屏方法!
  4. php xingnengfenxi_PHP 性能分析与实验:性能的微观分析
  5. CentOS+postfix+ExtMail+amavisd-new+Spam_Locker+DSpam配置指南:五、配置maildrop
  6. Elasticsearch——分词器对String的作用
  7. 收获,不止SQL优化——抓住SQL的本质--第八章
  8. 使用xorm工具,根据数据库自动生成 go 代码
  9. 【转】Nodejs链接Mysql批量添加 insert into
  10. 动软代码生成器注意事项-Sql注入
  11. STM32串口通信简介
  12. rose oracle双机切换故障,ROSE HA切换节点导致DG失败、恢复
  13. 矢量网络分析仪(矢网)组成和原理简介
  14. 关于Dev C++突然提示16位应用程序不兼容的问题
  15. 电脑桌面上文件夹图标右上角有双箭头
  16. 首届国际蜂业展在穗举办 零数科技受邀出席
  17. Adobe Acrobat XI Pro 软件下载安装详细教程
  18. 英语发音规则---E字母常见的发音组合有哪些
  19. 【Flume】Flume入门
  20. 以post的方式发请求,传参在url中

热门文章

  1. 使用StopWath统计代码执行耗时方法
  2. JQueryDOM和遍历
  3. 下载了JFLASH安装后还出现The select device is unknown to this version of the J-LINK software
  4. 同花顺服务器文件夹,同花顺的文件目录.doc
  5. Wireshark malformed packet
  6. Linux下安装oracle11.2.0.4
  7. 网易2018校园招聘:相反数 [python]
  8. OpenCv-C++-SURF特征检测
  9. FFB6D复现Bug
  10. Shell编程扩展正则表达式(egrep、awk)