[2019红帽杯]easyRE1题解

news2024/9/28 15:28:44

迷蒙马背眠,月随残梦天边远,淡淡起茶烟。

                                                        ——松尾芭蕉

目录

1.查壳

2.拖入64位IDA,找到主函数

3.静态分析主函数

4.wp


1.查壳

ELF文件,64bit

2.拖入64位IDA,找到主函数

 没有标明main函数,我们打开string窗口跟踪一下存储的字符串常量

 发现一个base64编码表,base64不懂的查看博文base64

点击这个编码表跟进

 将光标放在上面按下快捷键X查看调用这个字符串的地方

 点击进入

按下F5反汇编

 while ( v2 < v4 - 2 )
  {
    *(_BYTE *)(v6 + v2) = aAbcdefghijklmn[*(_BYTE *)(v3 + a1) >> 2];
    *(_BYTE *)(v6 + v2 + 1LL) = aAbcdefghijklmn[(16 * (*(_BYTE *)(v3 + a1) & 3)) | (*(_BYTE *)(v3 + 1LL + a1) >> 4)];
    *(_BYTE *)(v6 + v2 + 2LL) = aAbcdefghijklmn[(4 * (*(_BYTE *)(v3 + 1LL + a1) & 0xF)) | (*(_BYTE *)(v3 + 2LL + a1) >> 6)];
    *(_BYTE *)(v6 + v2 + 3LL) = aAbcdefghijklmn[*(_BYTE *)(v3 + 2LL + a1) & 0x3F];
    v3 += 3;
    v2 += 4;
  }

这是base64编码的代码,需要知道base64编码算法的特征

这个函数有传入的参数,应该不是主函数

将光标放在函数名出,按下快捷键N重命名为base64encode

我们继续回到string窗口,查看别的可疑字符串

我们用同样的方法找到You find me字符串被使用的函数

 这个函数应该是主函数

 可以重命名一下函数名,光标放在函数名上,按下快捷键N

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  int result; // eax
  unsigned __int64 v5; // rax
  __int64 v6; // rax
  int i; // [rsp+Ch] [rbp-114h]
  __int64 v8; // [rsp+10h] [rbp-110h]
  __int64 v9; // [rsp+18h] [rbp-108h]
  __int64 v10; // [rsp+20h] [rbp-100h]
  __int64 v11; // [rsp+28h] [rbp-F8h]
  __int64 v12; // [rsp+30h] [rbp-F0h]
  __int64 v13; // [rsp+38h] [rbp-E8h]
  __int64 v14; // [rsp+40h] [rbp-E0h]
  __int64 v15; // [rsp+48h] [rbp-D8h]
  __int64 v16; // [rsp+50h] [rbp-D0h]
  __int64 v17; // [rsp+58h] [rbp-C8h]
  char v18; // [rsp+60h] [rbp-C0h]
  char v19; // [rsp+61h] [rbp-BFh]
  char v20; // [rsp+62h] [rbp-BEh]
  char v21; // [rsp+63h] [rbp-BDh]
  char v22; // [rsp+64h] [rbp-BCh]
  char v23; // [rsp+65h] [rbp-BBh]
  char v24; // [rsp+66h] [rbp-BAh]
  char v25; // [rsp+67h] [rbp-B9h]
  char v26; // [rsp+68h] [rbp-B8h]
  char v27; // [rsp+69h] [rbp-B7h]
  char v28; // [rsp+6Ah] [rbp-B6h]
  char v29; // [rsp+6Bh] [rbp-B5h]
  char v30; // [rsp+6Ch] [rbp-B4h]
  char v31; // [rsp+6Dh] [rbp-B3h]
  char v32; // [rsp+6Eh] [rbp-B2h]
  char v33; // [rsp+6Fh] [rbp-B1h]
  char v34; // [rsp+70h] [rbp-B0h]
  char v35; // [rsp+71h] [rbp-AFh]
  char v36; // [rsp+72h] [rbp-AEh]
  char v37; // [rsp+73h] [rbp-ADh]
  char v38; // [rsp+74h] [rbp-ACh]
  char v39; // [rsp+75h] [rbp-ABh]
  char v40; // [rsp+76h] [rbp-AAh]
  char v41; // [rsp+77h] [rbp-A9h]
  char v42; // [rsp+78h] [rbp-A8h]
  char v43; // [rsp+79h] [rbp-A7h]
  char v44; // [rsp+7Ah] [rbp-A6h]
  char v45; // [rsp+7Bh] [rbp-A5h]
  char v46; // [rsp+7Ch] [rbp-A4h]
  char v47; // [rsp+7Dh] [rbp-A3h]
  char v48; // [rsp+7Eh] [rbp-A2h]
  char v49; // [rsp+7Fh] [rbp-A1h]
  char v50; // [rsp+80h] [rbp-A0h]
  char v51; // [rsp+81h] [rbp-9Fh]
  char v52; // [rsp+82h] [rbp-9Eh]
  char v53; // [rsp+83h] [rbp-9Dh]
  char v54[32]; // [rsp+90h] [rbp-90h]
  int v55; // [rsp+B0h] [rbp-70h]
  char v56; // [rsp+B4h] [rbp-6Ch]
  char v57; // [rsp+C0h] [rbp-60h]
  char v58; // [rsp+E7h] [rbp-39h]
  char v59; // [rsp+100h] [rbp-20h]
  unsigned __int64 v60; // [rsp+108h] [rbp-18h]

  v60 = __readfsqword(0x28u);
  v18 = 73;
  v19 = 111;
  v20 = 100;
  v21 = 108;
  v22 = 62;
  v23 = 81;
  v24 = 110;
  v25 = 98;
  v26 = 40;
  v27 = 111;
  v28 = 99;
  v29 = 121;
  v30 = 127;
  v31 = 121;
  v32 = 46;
  v33 = 105;
  v34 = 127;
  v35 = 100;
  v36 = 96;
  v37 = 51;
  v38 = 119;
  v39 = 125;
  v40 = 119;
  v41 = 101;
  v42 = 107;
  v43 = 57;
  v44 = 123;
  v45 = 105;
  v46 = 121;
  v47 = 61;
  v48 = 126;
  v49 = 121;
  v50 = 76;
  v51 = 64;
  v52 = 69;
  v53 = 67;
  memset(v54, 0, sizeof(v54));
  v55 = 0;
  v56 = 0;
  sub_4406E0(0LL, v54, 37LL);
  v56 = 0;
  LODWORD(v3) = sub_424BA0((const __m128i *)v54);
  if ( v3 == 36 )
  {
    for ( i = 0; ; ++i )
    {
      LODWORD(v5) = sub_424BA0((const __m128i *)v54);
      if ( i >= v5 )
        break;
      if ( (unsigned __int8)(v54[i] ^ i) != *(&v18 + i) )
      {
        result = -2;
        goto LABEL_13;
      }
    }
    sub_410CC0("continue!");
    memset(&v57, 0, 0x40uLL);
    v59 = 0;
    sub_4406E0(0LL, &v57, 64LL);
    v58 = 0;
    LODWORD(v6) = sub_424BA0((const __m128i *)&v57);
    if ( v6 == 39 )
    {
      v8 = base64encode((__int64)&v57);
      v9 = base64encode(v8);
      v10 = base64encode(v9);
      v11 = base64encode(v10);
      v12 = base64encode(v11);
      v13 = base64encode(v12);
      v14 = base64encode(v13);
      v15 = base64encode(v14);
      v16 = base64encode(v15);
      v17 = base64encode(v16);
      if ( !(unsigned int)sub_400360(v17, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        sub_410CC0("bye bye~");
      }
      result = 0;
    }
    else
    {
      result = -3;
    }
  }
  else
  {
    result = -1;
  }
LABEL_13:
  if ( __readfsqword(0x28u) != v60 )
    sub_444020();
  return result;
}

3.静态分析主函数

if ( v3 == 36 )
  {
    for ( i = 0; ; ++i )
    {
      LODWORD(v5) = sub_424BA0((const __m128i *)v54);
      if ( i >= v5 )
        break;
      if ( (unsigned __int8)(v54[i] ^ i) != *(&v18 + i) )
      {
        result = -2;
        goto LABEL_13;
      }
    }

关注这部分

if ( i >= v5 )
        break;

这是循环结束的条件

照着这个循环用脚本模拟一下,看看会输出什么

string=[73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,119,101,107,57,123,105,121,61,126,121,76,64,69,67]
flag=""
for i in range(0,35):
    flag+=chr(string[i]^i)
print(flag)

输出:

Info:The first four chars are `flag`

前四个字符是flag

继续往下分析

 是一组base64加密

黄色部分是一个strcmp函数

跟进off_6CC090

 继续跟进aVm0wd2vhuxhtwg

 这是一个base64编码将这个base64编码多次解码

解密网站

 不断解密

进入这个网址

 没什么用,纯属干扰解题的坑

下面有一个数据,使用快捷键X交叉引用查看一下

 到这个函数中分析一下

unsigned __int64 sub_400D35()
{
  unsigned __int64 result; // rax
  unsigned int v1; // [rsp+Ch] [rbp-24h]
  int i; // [rsp+10h] [rbp-20h]
  int j; // [rsp+14h] [rbp-1Ch]
  unsigned int v4; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v1 = sub_43FD20(0LL) - qword_6CEE38;
  for ( i = 0; i <= 1233; ++i )
  {
    sub_40F790(v1);
    sub_40FE60();
    sub_40FE60();
    v1 = (unsigned __int64)sub_40FE60() ^ 0x98765432;
  }
  v4 = v1;
  if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 102 && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 103 )
  {
    for ( j = 0; j <= 24; ++j )
      sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
  }
  result = __readfsqword(0x28u) ^ v5;
  if ( result )
    sub_444020();
  return result;
}
if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
  {
    for ( j = 0; j <= 24; ++j )
      sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
  }

v1是unsigned int 四个字节,高字节与低字节抑或分别是f和g,中间还有两个字节,那么很可能按位与其抑或就是flag

然后循环取出这四个字节与数据段异或就是flag

4.wp

data=[0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
four=['f','l','a','g']
data2=[]
flag=""
for i in range(4):
    data2.append(data[i]^ord(four[i]))   #两次异或等于没有异或
for i in range(len(data)):
    flag+=chr(data[i]^data2[i%4])
print(flag)

flag{Act1ve_Defen5e_Test}

其他题解请关注我的专栏reverse

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186602.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OSCP_VULHUB COVFEFE: 1

文章目录前言信息收集渗透过程权限提升前言 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/covfefe-1,199/ 攻击机&#xff1a;kali&#xff08;192.168.132.139&#xff09; 靶机&#xff1a;covfefe&#xff08;192.168.132.146&#xff09; 下载好靶机之后直接使…

vivo 超大规模消息中间件实践之路

作者&#xff1a;vivo 互联网存储技术团队-Luo Mingbo、中间件团队- Liu Runyun 本文根据“2022 vivo开发者大会"现场演讲内容整理而成。 本文主要介绍超大数据规模场景下分布式消息中间件在vivo的应用实践。 在线业务侧主要从RocketMQ集群部署架构、平台系统架构、日常运…

EMC基础:电容的频率特性

本文将对其中使用电容和电感降噪的对策进行介绍&#xff0c;这也可以称为“噪声对策的基础”。在这里使用简单的四元件模型。如果要进一步表达高频谐振时&#xff0c;可能需要更多的元件模型。 电容的频率特性 探讨利用电容器来降低噪声时&#xff0c;充分了解电容器的特性是…

设计模式——软件设计原则

目录 3.软件设计原则 3.1 开闭原则 3.2 里氏代换原则 3.3 依赖倒转原则 3.4 接口隔离原则 3.5 迪米特法则 3.6 合成复用原则 3.软件设计原则 在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;程序员要…

8、Servlet——Servlet生命周期、Servlet特性

目录 一、Servlet生命周期 1、生命周期的四个阶段 1.1 实例化 1.2 初始化 1.3 服务 1.4 销毁 2、Servlet执行流程 3、代码演示 二、 Servlet特性 1、线程安全问题 2、如何保证线程安全 一、Servlet生命周期 1、生命周期的四个阶段 1.1 实例化 当用户第一次访问Ser…

flutter裁剪三角形,并设置三角形最长边阴影(类似钉钉登录页右上角图标样式)

需求 需要使用flutter创建类似钉钉登录页右上角图表样式 过程 图标 图标直接从阿里巴巴图标库中下载png文件&#xff0c;并设置相应颜色 三角形阴影 样式的主要难点在三角形及三角形阴影这里 1、三角形的裁剪有两种方法&#xff1a; 第一种是 使用边框实现三角形 参考博客…

springboot自动加载--自定义启动器

创建自定义启动器 0、项目总览 1、创建项目&#xff0c;引入依赖 创建项目 spring-boot-jdbc-starter&#xff0c;引入依赖&#xff0c;pom文件如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apa…

b站黑马Vue2后台管理项目笔记——(1)登录功能

说明&#xff1a; 此项目中使用的是本地SQL数据库&#xff0c;Vue2。 其他功能请见本人后续的其他相关文章。 本文内容实现的最终效果如下图&#xff1a; 目录 一&#xff0e;登录功能的实现 1.登录页面的布局&#xff1a; &#xff08;1&#xff09;查看当前工作区是否干净…

读锁应该插队吗?什么是锁的升降级?

背景 ReentrantReadWriteLock可以设置公平或非公平&#xff0c;为什么&#xff1f; 读锁插队策略 每次获取响应锁之前都要检查能否获取 readerShouldBlockwriterShouldBlock 公平锁 final boolean writerShouldBlock() {return hasQueuedPredecessors(); } final boolean …

打造智慧工地,低代码平台助力基建行业全链路数字化升级

编者按&#xff1a;基建行业数字化转型需求迫切&#xff0c;低代码平台有助于加快数字化转型速度&#xff0c;赋能建筑工程企业升级。本文分析了低代码在基建行业中的应用价值&#xff0c;并指出基建行业对于低代码平台的需求&#xff0c;最后通过相关案例的展示了低代码平台在…

低代码平台解读:“低代码+PaaS”的技术创新实践

数字化转型已经成为必然趋势&#xff0c;几乎所有传统行业都喊出了数字化转型的口号。但在数字化转型中&#xff0c;很多企业面临着成本高、周期长的难题。低代码是其中一种破解难题的方式&#xff0c;如今的低代码已经是企业数字化的核心引擎。 低代码平台越来越多&#xff0…

数据结构——链表(五)

数据结构 文章目录数据结构前言一、什么是链表二、实现单链表1.单链表的结构2.单链表的初始化3.单链表的插入4.遍历链表5.链表长度总结前言 接下来学习一下链表&#xff0c;链表比数组用的更多。 一、什么是链表 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存…

《从0开始学大数据》之如何自己开发一个大数据SQL引擎

背景 大数据仓库 Hive&#xff0c;作为一个成功的大数据仓库&#xff0c;它将 SQL 语句转换成 MapReduce 执行过程&#xff0c;并把大数据应用的门槛下降到普通数据分析师和工程师就可以很快上手的地步。 但是 Hive 也有自己的问题&#xff0c;由于它使用自己定义的 Hive QL …

Linux常用命令——repquota命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) repquota 报表的格式输出磁盘空间限制的状态 补充说明 repquota命令以报表的格式输出指定分区&#xff0c;或者文件系统的磁盘配额信息。 语法 repquota(选项)(参数)选项 -a&#xff1a;列出在/etc/fstab文…

gRPC 基础(二)-- Go 语言版 gRPC-go

gRPC-Go Github gRPC的Go实现:一个高性能、开源、通用的RPC框架&#xff0c;将移动和HTTP/2放在首位。有关更多信息&#xff0c;请参阅Go gRPC文档&#xff0c;或直接进入快速入门。 一、快速入门 本指南通过一个简单的工作示例让您开始在Go中使用gRPC。 1.1 先决条件 Go:…

word排版技巧:这几种特殊版式轻松搞定

我们在许多报刊、杂志中会见到一些带有特殊效果的文档&#xff0c;如首字下沉、分栏排版、竖排文档等形式的排版效果。这些效果其实不是只有专业排版软才能实现&#xff0c;利用Word我们可以轻松完成这些排版效果。1、首字下沉首字下沉是一种突出显示段落中的第一个汉字的排版方…

3小时快速上手sharding-jdbc

今日目标 1、理解分库分表基础概念【垂直分库分表、水平分库分表】 2、能够说出sharding-jdbc为我们解决什么问题 3、理解sharding-jdbc中的关键名词 4、理解sharding-jdbc的整体架构及原理 5、掌握sharding-jdbc的集成方式1.分库分表介绍 1.1 分库分表概述 分库分表就是为了…

普元EOS_工作流引擎相关数据表记录---工作流工作笔记002

由于现在在用普元的工作流引擎,但是,说明文档中没有对数据表的说明 所以整理一下记录下来: 业务流程(com.eos.workflow.data.WFProcessDefine) 属性 名称 类型 processDefID 业务流程ID long processDefName 业务流程名称 String processChName 业务流程显示名称 String desc…

计算机图形学 第5章 二维变换与裁剪完结

目录中点分割直线段裁剪算法中点计算公式代码Liang-Barsky直线段裁剪算法⭐⭐⭐代码&#xff1a;多边形裁剪算法/Sutherland-Hodgman裁剪算法代码相关学习资料&#xff1a;中点分割直线段裁剪算法 中点分割直线段裁剪算法对Cohen-Sutherland直线裁剪算法的第3种情况做了改进&a…

Centos 安装部署 Sentinel

在微服务架构中&#xff0c;业务高峰时段&#xff0c;请求过多可能导致直接查询数据库&#xff0c;造成雪崩等事故。 一、雪崩问题 微服务调用链路中某个服务故障&#xff0c;引起整个链路中所有服务不可用。 解决方案 1&#xff09;超时处理 设置超时时间&#xff0c;请求超…