上次没写出,这次认真分析了一下,发现自己的调试水平也有了上涨,也看了一些C++逆向的文章,尤其是stl,发现C++的oop还是挺复杂,这题还没考啥虚函数的还行了。

一.拖入ida,找到主函数,还是挺容易的

int __cdecl main(int argc, const char **argv, const char **envp)
{
double v3; // xmm0_8
__int64 v4; // rax
__int64 v5; // rcx
__int64 v6; // r8
__int64 v7; // r9
__int64 v8; // rbx
__int64 v9; // rax
int v10; // ebx
__int64 v11; // rax
__int64 v12; // rax
__int64 v13; // rax
__int64 v14; // rax
__int64 v15; // rax
__int64 v16; // rax
char v18; // [rsp+0h] [rbp-140h]
__int64 v19; // [rsp+28h] [rbp-118h]
__int64 v20; // [rsp+30h] [rbp-110h]
int v21; // [rsp+3Ch] [rbp-104h]
char v22; // [rsp+40h] [rbp-100h]
char v23; // [rsp+60h] [rbp-E0h]
char v24; // [rsp+90h] [rbp-B0h]
char v25; // [rsp+AFh] [rbp-91h]
char v26; // [rsp+B0h] [rbp-90h]
char v27; // [rsp+DFh] [rbp-61h]
char v28; // [rsp+E0h] [rbp-60h]
int v29; // [rsp+104h] [rbp-3Ch]
char *v30; // [rsp+108h] [rbp-38h]
int *v31; // [rsp+110h] [rbp-30h]
_DWORD *v32; // [rsp+118h] [rbp-28h]
int *v33; // [rsp+120h] [rbp-20h]
int i; // [rsp+128h] [rbp-18h]
int v35; // [rsp+12Ch] [rbp-14h] v35 = 0;
std::vector<int,std::allocator<int>>::vector(&v24, argv, envp);
std::vector<bool,std::allocator<bool>>::vector(&v23);
std::allocator<char>::allocator(&v25);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v22, &unk_500E, &v25);
std::allocator<char>::~allocator(&v25);
v4 = std::operator<<<std::char_traits<char>>(&std::cout, "give me your key!");
std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
for ( i = 0; i <= 8; ++i )
{
std::istream::operator>>(&std::cin, &keys[i]);
std::__cxx11::to_string((std::__cxx11 *)&v26, keys[i], (unsigned int)keys[i], v5, v6, v7);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(&v22, &v26);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v26);// 输入9组字符
}
v32 = keys;
v33 = keys;
v31 = (int *)&unk_83E4;
while ( v33 != v31 )
{
v21 = *v33;
std::vector<int,std::allocator<int>>::push_back(&v24, &v21);
++v33;
} // 将输入的字符串存入vector中
v8 = std::vector<int,std::allocator<int>>::end(&v24);
v9 = std::vector<int,std::allocator<int>>::begin(&v24);
std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>,main::{lambda(int &)#1}>(// 每组异或1
v8,
v9,
v8);
v30 = &v24;
v20 = std::vector<int,std::allocator<int>>::begin(&v24);
v19 = std::vector<int,std::allocator<int>>::end(v30);// 类似头指针和尾指针
while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int,std::allocator<int>>>(&v20, &v19) )
{
v29 = *(_DWORD *)__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>::operator*(&v20);
std::allocator<char>::allocator(&v27);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v18, &unk_500E, &v27);// 定义string
std::allocator<char>::~allocator(&v27);
depart(v29, (__int64)&v18, v3); // 一波骚操作
{lambda(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> &)#1}::operator()(
(__int64)&func, // 一波替换
(__int64)&v18);
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v28, &v18);// string复制
v10 = (unsigned __int64){lambda(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>,int)#2}::operator()(
(__int64)&check, // 比较函数
(__int64)&v28,
v35) ^ 1;
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v28);
if ( (_BYTE)v10 )
{
v11 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong password!");
std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
system("pause");
exit(0);
}
++v35;
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v18);
__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>::operator++(&v20);// 头指针加一
}
v12 = std::operator<<<std::char_traits<char>>(&std::cout, "right!");
std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>);
v13 = std::operator<<<std::char_traits<char>>(&std::cout, "flag:MRCTF{md5(");
v14 = std::operator<<<char,std::char_traits<char>,std::allocator<char>>(v13, &v22);
v15 = std::operator<<<std::char_traits<char>>(v14, ")}");
std::ostream::operator<<(v15, &std::endl<char,std::char_traits<char>>);
v16 = std::operator<<<std::char_traits<char>>(
&std::cout,
"md5()->{32/upper case/put the string into the function and transform into md5 hash}");
std::ostream::operator<<(v16, &std::endl<char,std::char_traits<char>>);
system("pause");
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v22);
std::vector<bool,std::allocator<bool>>::~vector(&v23);
std::vector<int,std::allocator<int>>::~vector(&v24);
return 0;
}

把我的分析都写在注释里了,发现这个程序大体的逻辑是,输入9个数字,每个数字异或1,之后,遍历每个数字,进过depart函数,再进行替换,flag里面包含是md5加密的输入的9个数字。这里比较坑的有几点:

1.

当时一直没找到这个函数在哪。。原来点击那个Lambda就可以进入函数中了,lambda之前也百度了一下,之前一道加密题也碰到过,不过是python的语法,C++里面这个和python里面意思大体一致,相当于一个匿名函数,在主函数体里面定义,()里面是指的捕捉对象,具体,用的时候,再回忆。

2.

depart函数,这个递归感觉会劝退很多人,这个函数意思就是将数字分解,最后将除数和最后一个数字拼接成字符串。

二.根据我们的思路逆向写出一个脚本,最后的数字找个在线网站直接加密下就好了。

strs=["=zqE=z=z=z","=lzzE","=ll=T=s=s=E","=zATT","=s=s=s=E=E=E","=EOll=E","=lE=T=E=E=E","=EsE=s=z","=AT=lE=ll"]
def replacediy(str):
str=str.replace("O","0")
str=str.replace("l","1")
str=str.replace("z","2")
str=str.replace("E","3")
str=str.replace("A","4")
str=str.replace("s","5")
str=str.replace("G","6")
str=str.replace("T","7")
str=str.replace("B","8")
str=str.replace("q","9")
str=str.replace("="," ")
return str
flag=""
for i in strs:
tmp=replacediy(i).split(" ")[1:]
print tmp
sum=1
for j in range(len(tmp)):
sum*=int(tmp[j],10)
sum^=1
flag+=str(sum)
print flag

buu [MRCTF2020]EasyCpp的更多相关文章

  1. buu [MRCTF2020]keyboard

    密文: ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr ...

  2. Buu刷题

    前言 希望自己能够更加的努力,希望通过多刷大赛题来提高自己的知识面.(ง •_•)ง easy_tornado 进入题目 看到render就感觉可能是模板注入的东西 hints.txt给出提示,可以看 ...

  3. BUU刷题01

    [安洵杯 2019]easy_serialize_php 直接给了源代码 <?php $function = @$_GET['f']; function filter($img){ $filte ...

  4. buu学习记录(上)

    前言:菜鸡误入buu,差点被打吐.不过学到了好多东西. 题目名称: (1)随便注 (2)高明的黑客 (3)CheckIn (4)Hack World (5)SSRF Me (6)piapiapia ( ...

  5. [BUUCTF]REVERSE——[MRCTF2020]hello_world_go

    [MRCTF2020]hello_world_go 附件 步骤: 例行检查,64位程序,无壳 64位ida载入,检索程序里的字符串,有很多,直接检索flag 一个一个点过去,找到了flag 按a,提取 ...

  6. [BUUCTF]REVERSE——[MRCTF2020]Xor

    [MRCTF2020]Xor 附件 步骤: 例行检查,32位程序,无壳 32位ida载入,首先检索程序里的字符串,根据字符串的提示,跳转到程序的关键函数 根据flag,跳转到sub_401090函数 ...

  7. [BUUCTF]REVERSE——[MRCTF2020]Transform

    [MRCTF2020]Transform 附件 步骤: 例行检查,64位程序,无壳 64位ida载入,找到关键函数 一开始让我们输入一个长度为33位的字符串,之后使用数组dword_40F040打乱了 ...

  8. MRCTF2020 你传你🐎呢

    MRCTF2020 你传你 .htaccess mime检测 1.先尝试上传了一个文件,发现.jpg后缀的可以上传成功,但是用蚁剑连接时返回空数据 2.重新先上传一个.htaccess文件,让需要被上 ...

  9. BUU XSS COURSE 1 & [CISCN2019 华东北赛区]Web2

    BUU XSS COURSE 1 & [CISCN2019 华东北赛区]Web2 XSS的题目没怎么做过,比赛基本上也没有(=_=),总结下今天做的两题 都是看赵总视频现学现做的,这里附上学习 ...

随机推荐

  1. System Verilog过程块和方法

  2. 基于 BDD 理论的 Nebula 集成测试框架重构(上篇)

    本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 测试框架的演进 截止目前为止,在 Nebula Graph 的开发过程中 ...

  3. docker私有仓库搭建及使用

      1.下载官方镜像 sudo docker pull registry 下载完成后,docker images可以查看到pull下来的镜像registry 2.启动registry容器,用于提供私有 ...

  4. OFRecord 图片文件制数据集

    OFRecord 图片文件制数据集 在 OFRecord 数据格式 和 加载与准备 OFRecord 数据集 中,分别学习了 OFRecord 数据格式,以及如何将其它数据集转为 OFRecord 数 ...

  5. ARM NEON指令集优化理论与实践

    ARM NEON指令集优化理论与实践 一.简介 NEON就是一种基于SIMD思想的ARM技术,相比于ARMv6或之前的架构,NEON结合了64-bit和128-bit的SIMD指令集,提供128-bi ...

  6. 智能驾驶L2发展策略

    智能驾驶L2发展策略 智能驾驶L2,以们通俗的定义是,以高级辅助驾驶的产品为主的各种巡航产品,包括定速巡航,自适应巡航ACC,预见性巡航,智能巡航等等. 车辆驾驶是集注意力高度集中,手把控方向盘和换挡 ...

  7. Ucore lab1实验报告

    练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...

  8. httprunnermanager安装和配置

    服务端安装mysql数据库(建议5.7以上的,mysql安装教程),设置utf-8编码,创建对应的数据库,设置好相应的用户名,密码,然后启动mysql 下载httprunnermanager 安装ht ...

  9. linux文件内容列传行_行转列

    ================ 文件内容列传行_行转列  ================ 一.列转行 1.编辑测试文件 vi log.txt 16:23:00 8.2% 1773620k 16:2 ...

  10. SpringBoot数据访问(一) SpringBoot整合Mybatis

    前言 SpringData是Spring提供的一个用于简化数据库访问.支持云服务的开源框架.它是一个伞形项目,包含了大量关系型数据库及非关系型数据库的数据访问解决方案,其设计目的是为了使我们可以快速且 ...