XY_RE复现(五)

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

是一道魔改TEA加密

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

cpp 复制代码
#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

cpp 复制代码
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"相同,则那个随机数种子就是我们需要求的结果

cpp 复制代码
#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

cpp 复制代码
#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

cpp 复制代码
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

cpp 复制代码
__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'操作每一步

cpp 复制代码
_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解密 ,发现不对,前面应该还有一些操作

cpp 复制代码
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

python 复制代码
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}
相关推荐
用户962377954483 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主4 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954486 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机7 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机7 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954487 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star7 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954487 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher8 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行11 天前
网络安全总结
安全·web安全