陇原战“疫“2021 复现Re

继续在去年的比赛找,再水一篇

Re

EasyRe

发现关键函数

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  char v4; // [esp+0h] [ebp-E4h]
  char v5; // [esp+0h] [ebp-E4h]
  int i; // [esp+D0h] [ebp-14h]
  char *Str; // [esp+DCh] [ebp-8h]

  __CheckForDebuggerJustMyCode(&unk_41C015);
  Str = (char *)malloc(0x64u);
  sub_4110CD("Please input:", v4);
  sub_411401("%s", (char)Str);
  if ( j_strlen(Str) != 32 )
  {
    sub_4110CD("Sorry! Try again!\n", v5);
    exit(1);
  }
  dword_41A14C = sub_411406(Str);
  for ( i = 0; i < 8; ++i )
  {
    if ( *(_DWORD *)(dword_41A14C + 4 * i) != *(_DWORD *)&byte_41A058[4 * i] )
    {
      sub_4110CD("Sorry! Try again!\n", v5);
      exit(1);
    }
  }
  sub_4110CD("good! flag is flag{your input}!\n", v5);
  return 0;
}

然后发现在byte_41A058数组上有个奇怪的字符串,结果就是flag
flag{fc5e038d38a57032085441e7fe7010b0}

findme

int __cdecl main(int argc, const char **argv, const char **envp)
{
  sub_4024E0();
  puts("Please input your flag:");
  scanf("%s", Str);
  if ( sub_401610(Str) )
  {
    if ( off_403844("SETCTF2021", Str) )
      printf("Success!");
    else
      printf("Wrong!");
  }
  system("pause");
  return 0;
}

主函数,看起来好像挺简单。
在这里插入图片描述

然后发现strcmp?用交叉引用继续跟踪off_403844,发现函数sub_401A0E

int (__cdecl *sub_401A0E())(char *Str, char *)
{
  int (__cdecl *result)(char *, char *); // eax

  result = off_403840;
  off_403844 = (int (__cdecl *)(_DWORD, _DWORD))off_403840;
  return result;
}

是函数off_403840代替了strcmp,然后就是在上面的sub_401866
经过分析是RC4加密

int __cdecl sub_401866(char *Str, char *a2)
{
  unsigned int len; // eax
  char Data[512]; // [esp+1Ch] [ebp-51Ch] BYREF
  char key[256]; // [esp+21Ch] [ebp-31Ch] BYREF
  char v6[256]; // [esp+31Ch] [ebp-21Ch] BYREF
  char s[256]; // [esp+41Ch] [ebp-11Ch] BYREF
  unsigned int v8; // [esp+51Ch] [ebp-1Ch]
  int m; // [esp+520h] [ebp-18h]
  int k; // [esp+524h] [ebp-14h]
  size_t j; // [esp+528h] [ebp-10h]
  size_t i; // [esp+52Ch] [ebp-Ch]

  memset(s, 0, sizeof(s));
  memset(v6, 0, sizeof(v6));
  memset(key, 0, sizeof(key));
  for ( i = 0; i < strlen(Str); ++i )
    key[i] = Str[i];
  memset(Data, 0, sizeof(Data));
  for ( j = 0; j < strlen(a2); ++j )
    Data[j] = a2[j];
  v8 = strlen(Data);
  len = strlen(key);
  RC4_init(s, key, len);
  for ( k = 0; k <= 255; ++k )
    v6[k] = s[k];
  RC4_crpto((int)v6, (int)Data, v8);
  for ( m = 0; m <= 511; ++m )
  {
    if ( Data[m] != byte_403040[m] )
      return 0;
  }
  return 1;
}

脚本

#include <stdio.h>
void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len)
{
    int i = 0, j = 0;
    char k[256] = {0};
    unsigned char tmp = 0;

    for (i = 0; i < 256; i++)
    {
        s[i] = i;            // v6[i] = i1;
        k[i] = key[i % Len]; // v7 = i1++ % len;  *v6 = *(_BYTE *)(v7 + a2);
    }

    for (i = 0; i < 256; i++)
    {
        j = (j + s[i] + k[i]) % 256; // v3 = ((unsigned __int8)*result + result[v8] + v3) % 256;
        tmp = s[i];
        s[i] = s[j]; //交换s[i]和s[j]
        s[j] = tmp;
    }
}
void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len)
{
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;

    for (k = 0; k < Len; k++)
    {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;
        tmp = s[i];
        s[i] = s[j]; //交换s[x]和s[y]
        s[j] = tmp;
        t = (s[i] + s[j]) % 256;
        Data[k] ^= s[t]; //生成流密钥
    }
}
int main()
{
    unsigned char s[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};
    unsigned char k[256] = {"SETCTF2021"};
    unsigned char pData[] = {0xB7, 0x52, 0x85, 0xC1, 0x90,
                             0xE9, 0x07, 0xB8, 0xE4, 0x1A,
                             0xC3, 0xBD, 0x1D, 0x8E, 0x85,
                             0x46, 0x00, 0x21, 0x44, 0xAF,
                             0xEF, 0x70, 0x32, 0xB5, 0x11,
                             0xC6}; // byte_403040
    rc4_init(s, k, 10);
    rc4_crypt(s, (unsigned char *)pData, 26); //解密
    for (int i = 0; i < 26; i++)
    {
        printf("%c", (*((char *)pData + i)) & 0xff);
    }
    return 0;
}

SETCTF{Th1s_i5_E2_5tRcm9!}

power

arm-linux-gnueabi-as power -o power.o

int __cdecl main(int argc, const char **argv, const char **envp)
{
  aes *v3; // r4
  int i; // [sp+0h] [bp+0h]
  char v6[20]; // [sp+8h] [bp+8h] BYREF
  int v7[25]; // [sp+1Ch] [bp+1Ch] BYREF
  char v8[100]; // [sp+80h] [bp+80h] BYREF
  strcpy(v6, "this_is_a_key!!!");
  memset(v7, 0, sizeof(v7));
  memset(v8, 0, sizeof(v8));
  puts("input flag:");
  fgets((char *)v7, 100, (FILE *)stdin);
  v3 = (aes *)operator new(0xB0u);
  aes::aes(v3, v6);
  if ( strlen((const char *)v7) != 33 )
    exit(0);
  LOBYTE(v7[8]) = 0;
  for ( i = 0; i <= 31; i += 16 )
    aes::encryption_cbc(v3, (char *)&v7[i / 4u], &v8[2 * i]);
  if ( !strcmp(v8, "1030a9254d44937bed312da03d2db9adbec5762c2eca7b5853e489d2a140427b") )
    puts("yeah, you get it!");
  else
    puts("wrong!");
  return 0;
}

AES 加密 EBC模式
在这里插入图片描述
flag{y0u_found_the_aes_12113112}

EasyRE_Revenge

//IDC脚本
auto addr_start = 0x004117A0;//函数起始地址
auto addr_end = 0x00411E58;//函数结束地址
auto i=0,j=0;
for(i=addr_start;i<addr_end;i++){
    if(Dword(i) == 0x1E8){
        for(j=0 ; j<6; j++,i++ ){
            PatchByte(i,0x90);//0x90是nop表示的字节
        }
        i=i+4;
        for(j=0 ; j<3; j++,i++ ){
            PatchByte(i,0x90);
        }
        i=i+10;
        for(j=0 ; j<3; j++,i++ ){
            PatchByte(i,0x90);
        }
        i=i+5;
        for(j=0 ; j<1; j++,i++ ){
            PatchByte(i,0x90);
        }   
        i=i+3;
        for(j=0 ; j<2; j++,i++ ){
            PatchByte(i,0x90);
        }     
        i--;    
    }
} 
void __cdecl __noreturn sub_4117A0(int a1)
{
  int j; // [esp+D0h] [ebp-90h]
  int i; // [esp+DCh] [ebp-84h]
  int v3[27]; // [esp+E8h] [ebp-78h] BYREF
  _DWORD *v4; // [esp+154h] [ebp-Ch]

  v4 = malloc(0x64u);
  j_memset(v3, 0, 0x64u);
  v3[0] = 0x271E150C;
  v3[1] = 993143072;
  v3[2] = 1599491396;
  v3[3] = 1936351576;
  v3[4] = -1752267396;
  v3[5] = -1415407216;
  v3[6] = -809058892;
  v3[7] = -472198712;
  for ( i = 0; i < 8; ++i )
    v4[i] = *(_DWORD *)(a1 + 4 * i) ^ v3[(7 * i + 2) % 8];
  for ( j = 0; j < 8; ++j )
  {
    v4[j] ^= v4[j] << 7;
    v4[j] ^= v3[(7 * j + 3) % 8];
    v4[j] ^= v4[(5 * j + 3) % 8];
    v4[j] ^= v4[j] << 13;
    v4[j] ^= v3[(7 * j + 5) % 8];
    v4[j] ^= v4[j] << 17;
  }
}

脚本

from z3 import *
key = [0] * 8
v = [0] * 8
key[0] = BitVecVal(0x271E150C, 32)
key[1] = BitVecVal(0x3B322920, 32)
key[2] = BitVecVal(0x5F564D44, 32)
key[3] = BitVecVal(0x736A6158, 32)
key[4] = BitVecVal(0x978E857C, 32)
key[5] = BitVecVal(0xABA29990, 32)
key[6] = BitVecVal(0xCFC6BDB4, 32)
key[7] = BitVecVal(0xE3DAD1C8, 32)
flag = [BitVec(f"flag[{i}]", 32) for i in range(8)]
sol = Solver()
for i in range(8):
    v[i] = flag[i] ^ key[(7 * i + 2) % 8]
for j in range(8):
    v[j] ^= v[j] << 7
    v[j] ^= key[(7 * j + 3) % 8]
    v[j] ^= v[(5 * j + 3) % 8]
    v[j] ^= v[j] << 13
    v[j] ^= key[(7 * j + 5) % 8]
    v[j] ^= v[j] << 17
enc = [0xEEE8B042, 0x57D0EE6C, 0xF3F54B32, 0xD3F0B7D6,
       0x0A61C389, 0x38C7BA40, 0x0C3D9E2C, 0xD64A9284]
for i in range(8):
    sol.add(v[i] == enc[i])
if sol.check() == sat:
    mol = sol.model()
flag = [int.to_bytes(mol.eval(i).as_long(), 4,
                     byteorder="little").decode() for i in flag]
print("".join(flag))

Eat_something

拿webt反编译得到.o文件

int __cdecl w2c_checkright(int a1)
{
  int result; // eax
  __int64 v2; // [esp+20h] [ebp-168h]
  int v3; // [esp+30h] [ebp-158h]
  __int64 v4; // [esp+40h] [ebp-148h]
  __int64 v5; // [esp+48h] [ebp-140h]
  __int64 v6; // [esp+50h] [ebp-138h]
  __int64 v7; // [esp+58h] [ebp-130h]
  __int64 v8; // [esp+60h] [ebp-128h]
  __int64 v9; // [esp+68h] [ebp-120h]
  char v10; // [esp+C8h] [ebp-C0h]
  int v11; // [esp+CCh] [ebp-BCh]
  int v12; // [esp+D4h] [ebp-B4h]
  int v13; // [esp+D8h] [ebp-B0h]
  char *v14; // [esp+E4h] [ebp-A4h]
  int v15; // [esp+158h] [ebp-30h]
  unsigned int v16; // [esp+174h] [ebp-14h]

  if ( ++wasm_rt_call_stack_depth > 0x1F4u )
    wasm_rt_trap(7);
  v16 = w2c_g0 - 96;
  i32_store(w2c_memory, w2c_g0 - 96 + 88, ((unsigned __int64)(unsigned int)(w2c_g0 - 96) + 88) >> 32, a1);
  v15 = i32_load16_u(w2c_memory, 1048, 0);
  i32_store16(w2c_memory, v16 + 72, 0, v15);
  v9 = i64_load(w2c_memory, 1040, 0);
  i64_store(w2c_memory, v16 + 64, 0, v9, HIDWORD(v9));
  v8 = i64_load(w2c_memory, 1032, 0);
  i64_store(w2c_memory, v16 + 56, 0, v8, HIDWORD(v8));
  v7 = i64_load(w2c_memory, 1024, 0);
  i64_store(w2c_memory, v16 + 48, 0, v7, HIDWORD(v7));
  v6 = i64_load(w2c_memory, 1057, 0);
  i64_store(w2c_memory, v16 + 40, 0, v6, HIDWORD(v6));
  v5 = i64_load(w2c_memory, 1050, 0);
  i64_store(w2c_memory, v16 + 33, 0, v5, HIDWORD(v5));
  v4 = i64_load(w2c_memory, 1072, 0);
  i64_store(w2c_memory, v16 + 25, 0, v4, HIDWORD(v4));
  v2 = i64_load(w2c_memory, 1065, 0);
  i64_store(w2c_memory, v16 + 18, 0, v2, HIDWORD(v2));
  i32_store(w2c_memory, v16 + 12, ((unsigned __int64)v16 + 12) >> 32, 0);// i
  while ( i32_load(w2c_memory, v16 + 12LL) < 26 )// i<26
  {
    v14 = (char *)(i32_load(w2c_memory, v16 + 12LL) + v16 + 48);
    v13 = (unsigned __int8)i32_load8_u(w2c_memory, v14, 0);// v13=enc[i]
    v12 = i32_load(w2c_memory, v16 + 88LL);
    v11 = i32_load(w2c_memory, v16 + 12LL) + v12;
    v10 = i32_load8_u(w2c_memory, v11, 0);      // v10=flag[i]
    if ( v13 != (i32_load(w2c_memory, v16 + 12LL) ^ (2 * v10)) )
    {
      i32_store(w2c_memory, v16 + 92, ((unsigned __int64)v16 + 92) >> 32, v16 + 18);
      goto LABEL_9;
    }
    v3 = i32_load(w2c_memory, v16 + 12LL) + 1;  // i+=1
    i32_store(w2c_memory, v16 + 12, ((unsigned __int64)v16 + 12) >> 32, v3);
  }
  i32_store(w2c_memory, v16 + 92, ((unsigned __int64)v16 + 92) >> 32, v16 + 33);
LABEL_9:
  result = i32_load(w2c_memory, v16 + 92LL);
  --wasm_rt_call_stack_depth;
  return result;
}

发现数据
在这里插入图片描述

脚本

enc =   [0x86, 0x8B, 0xAA, 0x85, 0xAC, 0x89, 0xF0, 0xAF, 0xD8, 0x69, 
  0xD6, 0xDD, 0xB2, 0xBF, 0x6E, 0xE5, 0xAE, 0x99, 0xCC, 0xD5, 
  0xBC, 0x8B, 0xF2, 0x7D, 0x7A, 0xE3, 0x59, 0x6F, 0x75, 0x20, 
  0x61, 0x72, 0x65, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 
  0x00, 0x59, 0x6F, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x77, 
  0x72, 0x6F, 0x6E, 0x67, 0x21, 0x00]
flag  = []
for i in range(26):
    flag .append(chr((i ^ enc[i]) // 2))
print("".join(flag))
# CETCTF{Th0nk_Y0u_DocTOr51} 

O

java里什么也没有
run.log 好像在某比赛见过这东西,openjdk写的IdealGraph
发现奇怪的长数字
在这里插入图片描述
然后是b’V@QFQC~=a<<5dd==5<121c63<4c260`706cafd`x’
在run中找到了xorI 可以试着爆破最后发现异或5即可

脚本

import binascii
flag = [19703596266291286, 17170514749620305, 14918431467634785, 17170235578908772, 14073959292862517, 14355455746965553,
       14074174040703036, 15481536039092278, 27303497946234928, 33777409528692838]
s = ""
for i in flag:
    temp = hex(i)[2:].replace("00", "")
    s = s + temp[6:8] + temp[4:6] + temp[2:4] + temp[0:2]

s = binascii.a2b_hex(s)
for j in s:
    print(chr(j ^ 5), end="")
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值