XY_RE复现(五)

news2025/2/24 3:20:12

一,给阿姨倒一杯卡布奇诺

是一道魔改TEA加密

给出了一些初始化,然后输入的flag拆分,两两一组,通过for循环放入encrypt加密函数

#include <stdio.h>
#define uint32_t unsigned int

void decrypt(uint32_t *v, uint32_t *key)
{
    static uint32_t data1 = 0x5F797274;
    static uint32_t data2 = 0x64726168;
    int i;   // [rsp+20h] [rbp-10h]
    uint32_t sum; // [rsp+24h] [rbp-Ch]
    uint32_t v1;  // [rsp+28h] [rbp-8h]
    uint32_t v0;  // [rsp+2Ch] [rbp-4h]

    sum = 0x6E75316C * 32;
    uint32_t data1_tmp = v[0];
    uint32_t data2_tmp = v[1];
    v0 = v[0];
    v1 = v[1];
    for (i = 31; i >= 0; i--)
    {
        v1 -= ((v0 >> 5) + key[3]) ^ (v0 + sum) ^ (key[2] + 16 * v0) ^ (sum + i);
        v0 -= ((v1 >> 5) + key[1]) ^ (v1 + sum) ^ (key[0] + 16 * v1) ^ (sum + i);
        sum -= 0x6E75316C;
    }
    v[0] = v0 ^ data1;
    v[1] = v1 ^ data2;
    data1 = data1_tmp;
    data2 = data2_tmp;
}

int main()
{
    uint32_t key[4];   // [rsp+60h] [rbp-40h] BYREF
    uint32_t array[8]; // [rsp+70h] [rbp-30h]
    array[0] = 0x9B28ED45;
    array[1] = 0x145EC6E9;
    array[2] = 0x5B27A6C3;
    array[3] = 0xE59E75D5;
    array[4] = 0xE82C2500;
    array[5] = 0xA4211D92;
    array[6] = 0xCD8A4B62;
    array[7] = 0xA668F440;
    key[0] = 0x65766967;
    key[1] = 0x756F795F;
    key[2] = 0x7075635F;
    key[3] = 0x6165745F;
    for (int i = 0; i <= 7; i += 2)
    {
        decrypt(array + i, key);
    }
    for(int i=0; i<32; i++)
    {
        printf("%c", ((char*)array)[i]);
    }
    return 0;
}

// 133bffe401d223a02385d90c5f1ca377

二,ez_rand

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned __int64 v3; // rbx ,无符号64位整数型
  unsigned __int16 v4; // ax  , 无符号16位整数型
  int v5; // edi
  __int64 v6; // rsi
  int v7; // eax
  int v9[7]; // [rsp+20h] [rbp-50h]
  char v10; // [rsp+3Ch] [rbp-34h]
  __int16 v11; // [rsp+3Dh] [rbp-33h]
  __int128 v12; // [rsp+40h] [rbp-30h]
  __int64 v13; // [rsp+50h] [rbp-20h]
  int v14; // [rsp+58h] [rbp-18h]
  __int16 v15; // [rsp+5Ch] [rbp-14h]
  char v16; // [rsp+5Eh] [rbp-12h]

  v13 = 0i64;
  v12 = 0i64;
  v14 = 0;
  v15 = 0;
  v16 = 0;
  print((char *)&Format);
  scanf("%s");
  v9[0] = -362017699;
  v11 = 0;
  v3 = -1i64;
  v9[1] = 888936774;
  v9[2] = 119759538;
  v9[3] = -76668318;
  v9[4] = -1443698508;
  v9[5] = -2044652911;
  v9[6] = 1139379931;
  v10 = 77;
  do
    ++v3;
  while ( *((_BYTE *)&v12 + v3) );
  v4 = time64(0i64);
  srand(v4);
  v5 = 0;
  if ( v3 )
  {
    v6 = 0i64;
    do
    {
      v7 = rand();
      if ( (*((_BYTE *)&v12 + v6) ^ (unsigned __int8)(v7
                                                    + ((((unsigned __int64)(2155905153i64 * v7) >> 32) & 0x80000000) != 0i64)
                                                    + ((int)((unsigned __int64)(2155905153i64 * v7) >> 32) >> 7))) != *((_BYTE *)v9 + v6) )
      {
        print("Error???\n");
        exit(0);
      }
      ++v5;
      ++v6;
    }
    while ( v5 < v3 );
  }
  print("Right???\n");
  system("pause");
  return 0;
}

就是随机数v7与v9异或

随机数种子是通过time来取的,C语言中的srand(time)是伪随机,直接爆破,题目描述给出了flag头为"XYCTF",根据这个信息去爆破随机数种子,即我们将v9的前5位与生成的前五位随机数做异或,如果结果与“XYCTF”相同,则那个随机数种子就是我们需要求的结果 

#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
    unsigned char str[5] = { 0x5D, 0x0C, 0x6C, 0xEA, 0x46 };
    unsigned char random[6] = { 0 };
    unsigned char flag[6] = { 'X', 'Y', 'C', 'T', 'F', '\0' };
    for (int i = 0xFFFF; i >= 0; i--) {
        srand(i);
        for (int j = 0; j < 5; j++) {
            random[j] = rand() % 0xFF;
        }
        bool found = true;
        for (int j = 0; j < 5; j++) {
            if ((random[j] ^ str[j]) != flag[j]) {
                found = false;
                break;
            }
        }
        if (found) {
            cout << "Found! It is: " << i << endl;
            break;
        }
        else
            cout << "Not " << i << " Nope" << endl;
    }
    return 0;
}
//Found! It is: 21308

 爆破出随机数种子:21308

#include<iostream>
#include<cstdlib>
using namespace std;

int main()
{
    srand(21308);
    for (int i = 0; i < 29; i++) {
        int num = rand();
        cout << num << ",";
    }
    return 0;
}
//得到随机数4085,19210,5147,22630,16830,25853,6039,15416,9400,1281,32764,16374,8177,18485,16126,29528,5590,4777,18044,26256,25694,24259,10836,5327,13701,7138,5244,22538,13308,

 

随机数是16位的: 可以int num = rand() % 0xFF ;

得到:16位key

v9=[ 0x5D, 0x0C, 0x6C, 0xEA, 0x46, 0x19, 0xFC, 0x34, 0xB2, 0x62,
  0x23, 0x07, 0x62, 0x22, 0x6E, 0xFB, 0xB4, 0xE8, 0xF2, 0xA9,
  0x91, 0x12, 0x21, 0x86, 0xDB, 0x8E, 0xE9, 0x43, 0x4D]
key=[5,85,47,190,0,98,174,116,220,6,124,54,17,125,61,203,235,187,194,246,194,34,126,227,186,253,144,98,48]
flag=''
for i in range(len(v9)):
    flag+=chr(v9[i]^key[i])
print(flag)
#XYCTF{R@nd_1s_S0_S0_S0_easy!}

为什么就是v12^v7!=v9(?)

三,ez_cube

__int64 sub_140012930()
{
  int i; // [rsp+44h] [rbp+24h]
  char v2; // [rsp+64h] [rbp+44h]
  int v3; // [rsp+84h] [rbp+64h]

  sub_140011384(&unk_1400240A2);
  for ( i = 0; i < 9; ++i )
  {
    top[i] = &unk_14001CC24;                    // red
    under[i] = "Blue";
    right[i] = "Green";
    left[i] = "Orange";
    advance[i] = "Yellow";
    below[i] = "White";
  }
  under[1] = &unk_14001CC24;
  top[1] = "Green";
  right[1] = "Blue";
  while ( 1 )
  {
    do
      v2 = getchar();
    while ( v2 == 10 );
    switch ( v2 )
    {
      case 'R':
        sub_140011375();
        break;
      case 'U':
        sub_1400113BB();
        break;
      case 'r':
        sub_140011366();
        break;
      case 'u':
        sub_14001115E();
        break;
    }
    ++dword_14001F1C0;
    v3 = j_check();
    if ( v3 == 1 )
      break;
    if ( v3 == 2 )
      goto LABEL_19;
  }
  print(aGreatYouAreAGo);
LABEL_19:
  system("pause");
  return 0i64;
}

'R' 'U' 'r' 'u'操作每一步

_QWORD *sub_1400117F0()
{
  _QWORD *result; // rax
  __int64 v1; // [rsp+28h] [rbp+8h]
  __int64 v2; // [rsp+48h] [rbp+28h]
  __int64 v3; // [rsp+68h] [rbp+48h]
  __int64 v4; // [rsp+88h] [rbp+68h]
  __int64 v5; // [rsp+A8h] [rbp+88h]

  sub_140011384(&unk_1400240A2);
  v1 = top[2];
  v2 = top[5];
  v3 = top[8];
  top[2] = below[2];
  top[5] = below[5];
  top[8] = below[8];
  below[2] = left[6];
  below[5] = left[3];
  below[8] = left[0];
  left[0] = advance[8];
  left[3] = advance[5];
  left[6] = advance[2];
  advance[2] = v1;
  advance[5] = v2;
  advance[8] = v3;
  v4 = right[1];
  right[1] = right[3];
  right[3] = right[7];
  right[7] = right[5];
  right[5] = v4;
  v5 = right[0];
  right[0] = right[6];
  right[6] = right[8];
  right[8] = right[2];
  result = right;
  right[2] = v5;
  return result;
}

嗯,自己玩分析可能有点麻烦,想想应该可以直接写脚本。(自己用c++写了一下,不知道怎么搞四个字符操作那里,有点麻烦)先借一下别人的脚本吧

爆破的脚本还是需要再学一下。

四,What's this

Lua bytecode

可以找一个lua在线反编译网站。Lua 工具箱 (luatool.cn)

应该先变字符然后base64解密 ,发现不对,前面应该还有一些操作

function Xor(num1, num2)
  local tmp1 = num1
  local tmp2 = num2
  local str = ""
  repeat
    local s1 = tmp1 % 2
    local s2 = tmp2 % 2
    if s1 == s2 then
      str = "0" .. str
    else
      str = "1" .. str
    end
    tmp1 = math.modf(tmp1 / 2)
    tmp2 = math.modf(tmp2 / 2)
  until tmp1 == 0 and tmp2 == 0
  return tonumber(str, 2)
end

value = ""
output = ""
i = 1
while true do
  local temp = string.byte(flag, i)
  temp = string.char(Xor(temp, 8) % 256)
  value = value .. temp
  i = i + 1
  if i > string.len(flag) then
    break
  end
end
for _ = 1, 1000 do
  x = 3
  y = x * 3
  z = y / 4
  w = z - 5
  if w == 0 then
    print("This line will never be executed")
  end
end
for i = 1, string.len(flag) do
  temp = string.byte(value, i)
  temp = string.char(temp + 3)
  output = output .. temp
end
result = output:rep(10)
invalid_list = {
  1,
  2,
  3
}
for _ = 1, 20 do
  table.insert(invalid_list, 4)
end
for _ = 1, 50 do
  result = result .. "A"
  table.insert(invalid_list, 4)
end
for i = 1, string.len(output) do
  temp = string.byte(output, i)
  temp = string.char(temp - 1)
end
for _ = 1, 30 do
  result = result .. string.lower(output)
end
for _ = 1, 950 do
  x = 3
  y = x * 3
  z = y / 4
  w = z - 5
  if w == 0 then
    print("This line will never be executed")
  end
end
for _ = 1, 50 do
  x = -1
  y = x * 4
  z = y / 2
  w = z - 3
  if w == 0 then
    print("This line will also never be executed")
  end
end
require("base64")
obfuscated_output = to_base64(output)
obfuscated_output = string.reverse(obfuscated_output)
obfuscated_output = string.gsub(obfuscated_output, "g", "3")
obfuscated_output = string.gsub(obfuscated_output, "H", "4")
obfuscated_output = string.gsub(obfuscated_output, "W", "6")
invalid_variable = obfuscated_output:rep(5)
if obfuscated_output == "==AeuFEcwxGPuJ0PBNzbC16ctFnPB5DPzI0bwx6bu9GQ2F1XOR1U" then
  print("You get the flag.")
else
  print("F**k!")
end

先异或8后+3

import  base64
enc='==AeuFEcwxGPuJ0PBNzbC16ctFnPB5DPzI0bwx6bu9GQ2F1XOR1U'
print(enc[::-1])
str=list(enc[::-1])
for i in range(len(str)):
    if str[i]=='3':
        str[i]='g'
    elif str[i]=='4':
        str[i]='H'
    elif str[i]=='6':
        str[i]="W"
print(''.join(str))
ant='U1ROX1F2QG9ubWxwb0IzPD5BPnFtcW1CbzNBP0JuPGxwcEFueA=='
date=base64.b64decode(ant)
flag = ""
for i in date:
   flag += chr((i - 3) ^ 8)
print(flag)
#XYCTF{5dcbaed781363fbfb7d8647c1aee6c}

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

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

相关文章

笨蛋学C++之 C++连接数据库

笨蛋学C 之 VS2019使用C连接数据库 创建数据库SQL语句VS2019选择空项目&#xff0c;点击下一步创建输入项目名称&#xff0c;点击创建创建成功点击新建项创建源文件因为mysql是64位&#xff0c;此时的c项目是86位&#xff0c;所以这里需要将项目修改为x64位点击项目 -> 0501…

linux 单机安装consul

sudo yum install -y yum-utils && sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo && sudo yum -y install consul#添加consul配置文件 nano /etc/consul.d/server.json {"server": true,"boots…

Python异步Redis客户端与通用缓存装饰器

前言 这里我将通过 redis-py 简易封装一个异步的Redis客户端&#xff0c;然后主要讲解设计一个支持各种缓存代理&#xff08;本地内存、Redis等&#xff09;的缓存装饰器&#xff0c;用于在减少一些不必要的计算、存储层的查询、网络IO等。 具体代码都封装在 HuiDBK/py-tools: …

使用 uni-app 开发 iOS 应用的操作步骤

哈喽呀&#xff0c;大家好呀&#xff0c;淼淼又来和大家见面啦&#xff0c;上一期和大家一起探讨了使用uniapp开发iOS应用的优势及劣势之后有许多小伙伴想要尝试使用uniapp开发iOS应用&#xff0c;但是却不懂如何使用uniapp开发iOS应用&#xff0c;所以这一期淼淼就来给你们分享…

nginx--平滑升级

失败了&#xff0c;等我拍好错继续更新 命令 选项说明 帮助: -? -h 使用指定的配置文件: -c 指定配置指令:-g 指定运行目录:-p 测试配置文件是否有语法错误:-t -T 打印nginx的版本信息、编译信息等:-v -V 发送信号: -s 示例: nginx -s reload 信号说明 立刻停止服务:stop,相…

【C++】学习笔记——string_3

文章目录 六、string类5. string类的操作6. string类的转换7. string类的模拟实现 未完待续 搭配文档食用 六、string类 5. string类的操作 上面的函数中&#xff0c;有些是不常用的&#xff0c;咱们只挑几个重要的进行讲解。 c_str 就是将字符串转换成 C语言 字符串的格式。…

[Java EE] 多线程(六):线程池与定时器

1. 线程池 1.1 什么是线程池 我们前面提到,线程的创建要比进程开销小,但是如果线程的创建/销毁比较频繁,开销也会比较大.所以我们便引入了线程池,线程池的作用就是提前把线程都创建好,放到用户态代码中写的数据结构中,后面就可以随用随取. 线程池最大的好处就是减少每次启动,…

Python中动画显示与gif生成

1. 动画生成 主要使用的是 matplotlib.animation &#xff0c;具体示例如下&#xff1a; import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np fig, ax plt.subplots() t np.linspace(0, 3, 40) g -9.81 v0 12 z g * t**2 / …

【Python函数和类6/6】类与对象

目录 目标 类与对象 类的定义 栗子 实例化对象 属性和方法的调用 特殊的self参数 类方法的其它参数 函数与方法的区别 总结 目标 在前面的博客当中&#xff0c;我们已经接触了一部分封装。比如&#xff1a;将数据扔进列表中&#xff0c;这就是一个简单…

短视频素材去哪里搬运?短视频素材有哪些类型?

在这个数字化和视觉传达至关重要的时代&#xff0c;选择合适的视频素材对于提升视频内容的吸引力和观众参与度至关重要。无论您是一名广告制片人、社交媒体经理还是独立视频制作者&#xff0c;以下这些精选的视频素材网站将为您提供从高清视频到特效资源的全面支持&#xff0c;…

工厂模式和策略模式区别

工厂模式和策略模式都是面向对象设计模式&#xff0c;但它们的目的和应用场景有所不同。 工厂模式是一种创建型设计模式&#xff0c;旨在通过使用一个工厂类来创建对象&#xff0c;而不是直接使用new关键字来创建对象。这样做可以使系统更容易扩展和维护&#xff0c;因为新的对…

reactjs后台管理系统搭建

1 通过yarn 模板创建reactjs项目 yarn create vite reactjs-antdesign-admin --template react-ts 2 基础路由测试 定义一个router/index.tsx&#xff0c;里面定义路由组件 const Router: React.FC () > {return (<HashRouter><Switch><Route path"…

Edge浏览器使用心得与深度探索

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

信息时代的智慧导航:高效搜索、信息筛选与信任构建的全面指南!

文章目录 一、高效搜索&#xff1a;快速定位目标信息的秘诀二、信息筛选&#xff1a;去伪存真&#xff0c;找到有价值的信息三、信任构建&#xff1a;深入了解与直接沟通《搜索之道&#xff1a;信息素养与终身学习的新引擎》亮点内容简介目录获取方式 随着科技的飞速发展&#…

前端基础学习html(2)

目录 表格标签&#xff1a; 列表标签&#xff1a; 表格标签&#xff1a; <!-- 表格基本架构 --><!-- tr表示一行&#xff0c;td表示一行内单元格 --><!--th为第一行表头加粗居中显示 --><table border"1"><thead><tr><th&g…

用Stream流方式合并两个list集合(部分对象属性重合)

一、合并出共有部分 package com.xu.demo.test;import java.util.Arrays; import java.util.List; import java.util.stream.Collectors;public class ListMergeTest1 {public static void main(String[] args) {List<User> list1 Arrays.asList(new User(1, "Alic…

【linux学习指南】linux指令与实践文件编写

文章目录 &#x1f4dd;前言&#x1f320; linux目录结构&#x1f309;linux命令介绍 &#x1f320;pwd命令&#x1f309;mkdir指令&#xff08;重要&#xff09; &#x1f320;cd 指令&#x1f309;touch指令 &#x1f320;rmdir指令 && rm 指令&#xff08;重要&…

nginx--配置文件

组成 主配置文件&#xff1a;nginx.conf 子配置文件&#xff1a;include conf.d/*.conf 协议相关的配置文件&#xff1a;fastcgi uwsgi scgi等 mime.types&#xff1a;⽀持的mime类型&#xff0c;MIME(Multipurpose Internet Mail Extensions)多用途互联⽹网邮件扩展类型&…

KUKA机器人KR3 R540维护保养——涂润滑脂

KUKA机器人在保养时少不了润滑脂&#xff0c;不同型号的机器人需要的润滑脂类型也不一样&#xff0c;保养时注意选用合适的润滑脂。本篇文章以KUKA机器人KR3 R540为例&#xff0c;在轴盖板 A2、A3、A5 的内侧涂上润滑脂。 一、涂润滑脂的作用 拆开机器人一个轴的盖板&am…

链表面试题2

1&#xff0c;合并两个有序链表 我们先定义一个虚拟节点newH&#xff0c; 然后按照上图所走&#xff0c;但是当其中一个链表走空时&#xff0c;我们只需返回另一个链表即可 class Solution {public ListNode mergeTwoLists(ListNode headA, ListNode headB) {ListNode newhead…