Mas0n
to be reverse engineer🐧
翻车鱼

2021DASCTF实战精英夏令营暨DASCTF July X CBCTF 4th

2021DASCTF实战精英夏令营暨DASCTF July X CBCTF 4th

标题好长= =

Rev

shellcode

拿到题目

目录结构

.
├── main.bat
├── part1.exe
├── part2.bin
└── part3.exe
cat main.bat
set /p FLAG=please input your flag:
start /MIN part1.exe
echo checking...
sleep 2 && part3

先看part1,很容易发现是Golang写的= =,ida7.6打开

我用的freeware版本,不知道我的网络还是啥,提示连接不到远程服务器,所以没法反编译成伪代码,不过不碍事,看了看汇编,大体知道这是一个HTTP Server,绑定本地端口8080,开了两条api

/hello:name/shell/:key

直接看part3,

int __cdecl main(int argc, const char **argv, const char **envp)
{
  HANDLE v3; // eax
  void *v4; // esi
  int result; // eax
  DWORD v6; // edi
  void (*v7)(void); // eax
  void (*v8)(void); // [esp+8h] [ebp-Ch]
  DWORD NumberOfBytesRead; // [esp+Ch] [ebp-8h] BYREF

  v3 = CreateFileA("part2.bin", 0x80000000, 0, 0, 4u, 0, 0);
  v4 = v3;
  if ( v3 == (HANDLE)-1 )
  {
    sub_401010("CreateFile Error");
    result = -1;
  }
  else
  {
    v6 = GetFileSize(v3, 0);
    v7 = (void (*)(void))VirtualAlloc(0, v6, 0x1000u, 0x40u);
    v8 = v7;
    if ( v7 )
    {
      NumberOfBytesRead = 0;
      ReadFile(v4, v7, v6, &NumberOfBytesRead, 0);
      v8();
      result = 0;
    }
    else
    {
      sub_401010("VirtualAlloc Error");
      CloseHandle(v4);
      result = -1;
    }
  }
  return result;
}

加载了part2.bin的shellcode,上动态调试

int sub_1E0005()
{
  char v1[8]; // [esp+0h] [ebp-BCh] BYREF
  int (__stdcall *v2)(char *, int, _DWORD, _DWORD, _DWORD); // [esp+8h] [ebp-B4h]
  void (__stdcall *v3)(int); // [esp+Ch] [ebp-B0h]
  int (__stdcall *v4)(int, int, int, int *); // [esp+10h] [ebp-ACh]
  int (__stdcall *v5)(_DWORD, unsigned __int8 *, int, int); // [esp+14h] [ebp-A8h]
  void (__stdcall *v6)(int, _DWORD, _DWORD, _DWORD, _DWORD); // [esp+18h] [ebp-A4h]
  int (__stdcall *v7)(int, char *, int, _DWORD, _DWORD, int, _DWORD, _DWORD); // [esp+20h] [ebp-9Ch]
  int (__stdcall *v8)(int, char *, char *, char *, _DWORD, _DWORD, int, _DWORD); // [esp+24h] [ebp-98h]
  int v9; // [esp+28h] [ebp-94h]
  int (*v10)(void); // [esp+2Ch] [ebp-90h]
  int v11; // [esp+30h] [ebp-8Ch]
  int v12; // [esp+34h] [ebp-88h]
  int v13; // [esp+38h] [ebp-84h]
  int v14; // [esp+3Ch] [ebp-80h]
  char v15[16]; // [esp+40h] [ebp-7Ch] BYREF
  char v16[8]; // [esp+50h] [ebp-6Ch] BYREF
  int v17; // [esp+58h] [ebp-64h]
  int v18; // [esp+5Ch] [ebp-60h] BYREF
  char v19[4]; // [esp+60h] [ebp-5Ch] BYREF
  char v20[40]; // [esp+64h] [ebp-58h] BYREF
  char v21[16]; // [esp+8Ch] [ebp-30h] BYREF
  char v22[12]; // [esp+9Ch] [ebp-20h] BYREF
  char v23[12]; // [esp+A8h] [ebp-14h] BYREF
  int v24; // [esp+B4h] [ebp-8h]
  char v25[4]; // [esp+B8h] [ebp-4h] BYREF

  ((void (__cdecl *)(char *))unk_1E0480)(v1);
  strcpy(v15, "Hello GuiShou");
  strcpy(v19, "Tip");
  v11 = v5(0, &unk_400000, 4096, 64);
  v10 = (int (*)(void))v5(0, &unk_400000, 4096, 64);
  v9 = 0x4000000;
  strcpy(v22, "127.0.0.1");
  strcpy(v16, "8080");
  strcpy(v25, "GET");
  strcpy(v21, "/shell/voidrn");
  strcpy(v20, "Mozilla/5.0 (Windows NT 6.1; rv:11.0)");
  strcpy(v23, "HTTP/1.0");
  v14 = 1;
  v18 = -1;
  v24 = 0;
  v12 = v2(v20, 1, 0, 0, 0); // Http new
  v13 = v7(v12, v22, 8080, 0, 0, 3, 0, 0);  // Http init 
  v17 = v8(v13, v25, v21, v23, 0, 0, v9, 0); // Http open
  v6(v17, 0, 0, 0, 0); // Http send
  while ( v14 && v18 )
  {
    v14 = v4(v17, v24 + v11, 4096, &v18);  // Http get resonse Text
    v24 += v18; // Http response Text
  }
  v3(v17); // Http free
  v3(v13); // Http free
  v3(v12); // Http free
  ((void (__cdecl *)(int, int, int (*)(void)))unk_1E059F)(v11, v24, v10);
  return v10();
}

大胆推测,调用/shell/void,而后将响应传入((void (__cdecl *)(int, int, int (*)(void)))unk_1E059F)这个方法

int __cdecl sub_1E059F(int a1, unsigned int a2, int a3)
{
  char v4[47]; // [esp+40h] [ebp-90h]
  char v5[56]; // [esp+6Fh] [ebp-61h] BYREF
  char v6[25]; // [esp+A7h] [ebp-29h] BYREF
  unsigned int v7; // [esp+C0h] [ebp-10h]
  unsigned int i; // [esp+C4h] [ebp-Ch]
  int v9; // [esp+C8h] [ebp-8h]
  unsigned __int8 v10; // [esp+CFh] [ebp-1h]

  v4[0] = -1;
  v4[1] = -1;
  v4[2] = -1;
  v4[3] = -1;
  v4[4] = -1;
  v4[5] = -1;
  v4[6] = -1;
  v4[7] = -1;
  v4[8] = -1;
  v4[9] = -1;
  v4[10] = -1;
  v4[11] = -1;
  v4[12] = -1;
  v4[13] = -1;
  v4[14] = -1;
  v4[15] = -1;
  v4[16] = -1;
  v4[17] = -1;
  v4[18] = -1;
  v4[19] = -1;
  v4[20] = -1;
  v4[21] = -1;
  v4[22] = -1;
  v4[23] = -1;
  v4[24] = -1;
  v4[25] = -1;
  v4[26] = -1;
  v4[27] = -1;
  v4[28] = -1;
  v4[29] = -1;
  v4[30] = -1;
  v4[31] = -1;
  v4[32] = -1;
  v4[33] = -1;
  v4[34] = -1;
  v4[35] = -1;
  v4[36] = -1;
  v4[37] = -1;
  v4[38] = -1;
  v4[39] = -1;
  v4[40] = -1;
  v4[41] = -1;
  v4[42] = -1;
  v4[43] = 62;
  v4[44] = -1;
  v4[45] = -1;
  v4[46] = -1;
  qmemcpy(v5, "?456789:;<=", 11);
  v5[11] = -1;
  v5[12] = -1;
  v5[13] = -1;
  v5[14] = -1;
  v5[15] = -1;
  v5[16] = -1;
  v5[17] = -1;
  v5[18] = 0;
  v5[19] = 1;
  v5[20] = 2;
  v5[21] = 3;
  v5[22] = 4;
  v5[23] = 5;
  v5[24] = 6;
  v5[25] = 7;
  v5[26] = 8;
  v5[27] = 9;
  v5[28] = 10;
  v5[29] = 11;
  v5[30] = 12;
  v5[31] = 13;
  v5[32] = 14;
  v5[33] = 15;
  v5[34] = 16;
  v5[35] = 17;
  v5[36] = 18;
  v5[37] = 19;
  v5[38] = 20;
  v5[39] = 21;
  v5[40] = 22;
  v5[41] = 23;
  v5[42] = 24;
  v5[43] = 25;
  v5[44] = -1;
  v5[45] = -1;
  v5[46] = -1;
  v5[47] = -1;
  v5[48] = -1;
  v5[49] = -1;
  v5[50] = 26;
  v5[51] = 27;
  v5[52] = 28;
  v5[53] = 29;
  v5[54] = 30;
  v5[55] = 31;
  qmemcpy(v6, " !\"#$%&'()*+,-./0123", 20);
  v6[20] = -1;
  v6[21] = -1;
  v6[22] = -1;
  v6[23] = -1;
  v6[24] = -1;
  if ( (a2 & 3) != 0 )
    return 0;
  v9 = 0;
  for ( i = 0; i < a2 && *(_BYTE *)(i + a1) != 61; ++i )
  {
    if ( *(char *)(i + a1) < 43 || *(char *)(i + a1) > 122 )
      return 0;
    v10 = v4[*(unsigned __int8 *)(i + a1)];
    if ( v10 == 255 )
      return 0;
    v7 = i & 3;
    if ( (i & 3) != 0 )
    {
      switch ( v7 )
      {
        case 1u:
          *(_BYTE *)(v9 + a3) |= ((int)v10 >> 4) & 3;
          *(_BYTE *)(++v9 + a3) = 16 * (v10 & 0xF);
          break;
        case 2u:
          *(_BYTE *)(v9 + a3) |= ((int)v10 >> 2) & 0xF;
          *(_BYTE *)(++v9 + a3) = (v10 & 3) << 6;
          break;
        case 3u:
          *(_BYTE *)(v9 + a3) |= v10;
          ++v9;
          break;
      }
    }
    else
    {
      *(_BYTE *)(v9 + a3) = 4 * v10;
    }
  }
  return v9;
}

后半段一看,明显是base64算法

运行part1,再去康康这条api返回了什么

https://cdn.shi1011.cn/2021/08/3d800d49732376d6c6801740f9e30964.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

盲猜还是shellcode

开着part1,继续看加载的shellcode

int sub_25C0005()
{
  int result; // eax
  char v1[4]; // [esp+0h] [ebp-C0h] BYREF
  int (__stdcall *v2)(_DWORD, char *, _DWORD, int); // [esp+4h] [ebp-BCh]
  void (__stdcall *v3)(char *, char *, int); // [esp+28h] [ebp-98h]
  char v4[35]; // [esp+2Ch] [ebp-94h]
  char v5[3]; // [esp+4Fh] [ebp-71h] BYREF
  char v6[44]; // [esp+54h] [ebp-6Ch] BYREF
  char v7[44]; // [esp+80h] [ebp-40h] BYREF
  char v8[8]; // [esp+ACh] [ebp-14h] BYREF
  char v9[8]; // [esp+B4h] [ebp-Ch] BYREF
  int i; // [esp+BCh] [ebp-4h]

  ((void (__cdecl *)(char *))unk_25C048A)(v1);
  v7[0] = 0;
  v7[1] = 0;
  v7[2] = 0;
  v7[3] = 0;
  v7[4] = 0;
  v7[5] = 0;
  v7[6] = 0;
  v7[7] = 0;
  v7[8] = 0;
  v7[9] = 0;
  v7[10] = 0;
  v7[11] = 0;
  v7[12] = 0;
  v7[13] = 0;
  v7[14] = 0;
  v7[15] = 0;
  v7[16] = 0;
  v7[17] = 0;
  v7[18] = 0;
  v7[19] = 0;
  v7[20] = 0;
  v7[21] = 0;
  v7[22] = 0;
  v7[23] = 0;
  v7[24] = 0;
  v7[25] = 0;
  v7[26] = 0;
  v7[27] = 0;
  v7[28] = 0;
  v7[29] = 0;
  v7[30] = 0;
  v7[31] = 0;
  v7[32] = 0;
  v7[33] = 0;
  v7[34] = 0;
  v7[35] = 0;
  v7[36] = 0;
  v7[37] = 0;
  v7[38] = 0;
  v7[39] = 0;
  v7[40] = 0;
  v7[41] = 0;
  v7[42] = 0;
  v7[43] = 0;
  strcpy(v9, "FLAG");
  v3(v9, v7, 44);
  v6[0] = 0;
  v6[1] = 0;
  v6[2] = 0;
  v6[3] = 0;
  v6[4] = 0;
  v6[5] = 0;
  v6[6] = 0;
  v6[7] = 0;
  v6[8] = 0;
  v6[9] = 0;
  v6[10] = 0;
  v6[11] = 0;
  v6[12] = 0;
  v6[13] = 0;
  v6[14] = 0;
  v6[15] = 0;
  v6[16] = 0;
  v6[17] = 0;
  v6[18] = 0;
  v6[19] = 0;
  v6[20] = 0;
  v6[21] = 0;
  v6[22] = 0;
  v6[23] = 0;
  v6[24] = 0;
  v6[25] = 0;
  v6[26] = 0;
  v6[27] = 0;
  v6[28] = 0;
  v6[29] = 0;
  v6[30] = 0;
  v6[31] = 0;
  v6[32] = 0;
  v6[33] = 0;
  v6[34] = 0;
  v6[35] = 0;
  v6[36] = 0;
  v6[37] = 0;
  v6[38] = 0;
  v6[39] = 0;
  v6[40] = 0;
  v6[41] = 0;
  v6[42] = 0;
  v6[43] = 0;
  v4[0] = 100;
  v4[1] = 46;
  v4[2] = -112;
  v4[3] = 52;
  v4[4] = 65;
  v4[5] = -40;
  v4[6] = 36;
  v4[7] = -53;
  v4[8] = 82;
  v4[9] = 46;
  v4[10] = -5;
  v4[11] = 57;
  v4[12] = 62;
  v4[13] = -111;
  v4[14] = 7;
  v4[15] = 14;
  v4[16] = -106;
  v4[17] = -10;
  v4[18] = 60;
  v4[19] = 9;
  v4[20] = -100;
  v4[21] = 33;
  v4[22] = -110;
  v4[23] = 33;
  v4[24] = -78;
  v4[25] = -52;
  v4[26] = -97;
  v4[27] = 81;
  v4[28] = 72;
  v4[29] = 99;
  v4[30] = 76;
  v4[31] = -113;
  v4[32] = 114;
  v4[33] = 93;
  v4[34] = -65;
  qmemcpy(v5, "lQv", sizeof(v5));
  ((void (__cdecl *)(char *, int, char *))unk_25C05BA)(v7, 38, v6);
  for ( i = 0; i < 38; ++i )
  {
    result = (unsigned __int8)v6[i];
    if ( result != (unsigned __int8)v4[i] )
      return result;
  }
  strcpy(v8, "Correct");
  return v2(0, v8, 0, 64);
}

看到末尾v6与v4对比,往上康康((void (__cdecl *)(char *, int, char *))unk_25C05BA)

int __cdecl sub_25C05BA(int a1, int a2, int a3)
{
  int result; // eax
  char v4[256]; // [esp+0h] [ebp-124h]
  int v5; // [esp+100h] [ebp-24h]
  int v6; // [esp+104h] [ebp-20h]
  char v7[12]; // [esp+108h] [ebp-1Ch] BYREF
  int j; // [esp+114h] [ebp-10h]
  int v9; // [esp+118h] [ebp-Ch]
  int i; // [esp+11Ch] [ebp-8h]
  char v11; // [esp+123h] [ebp-1h]

  strcpy(v7, "golangc2");
  v6 = 8;
  for ( i = 0; i < 256; ++i )
    v4[i] = i;
  v9 = 0;
  for ( i = 0; i < 256; ++i )
  {
    v9 = ((unsigned __int8)v4[i] + v9 + v7[i % v6]) % 256;
    v11 = v4[i];
    v4[i] = v4[v9];
    v4[v9] = v11;
  }
  v9 = 0;
  i = 0;
  for ( j = 0; ; ++j )
  {
    result = j;
    if ( j >= a2 )
      break;
    i = (i + 1) % 256;
    v9 = (v9 + (unsigned __int8)v4[i]) % 256;
    v11 = v4[i];
    v4[i] = v4[v9];
    v4[v9] = v11;
    v5 = ((unsigned __int8)v4[v9] + (unsigned __int8)v4[i]) % 256;
    v11 = v4[v5];
    *(_BYTE *)(j + a3) = v11 ^ *(_BYTE *)(j + a1);
  }
  return result;
}

一眼看穿是RC4,key拿到手golangc2

那么直接去拿密文就行了,这里直接运行到调用RC4前,以防动态运行时它再加点料,然后dump下来解密完事

https://cdn.shi1011.cn/2021/08/2e16bce623027fc9ddbc480062c03770.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

replace

lua题,32位,试了下bindiff,根本识别不出来 = =

那就dump下luac,unluac跑出脚本来

local L0_1, L1_1, L2_1, L3_1, L4_1, L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1
L0_1 = require
L1_1 = "enclib"
L0_1 = L0_1(L1_1)
enclib = L0_1
function L0_1(A0_2)
  local L1_2, L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2
  L1_2 = string
  L1_2 = L1_2.len
  L2_2 = A0_2
  L1_2 = L1_2(L2_2)
  L2_2 = {}
  L3_2 = {}
  L4_2 = 0
  L5_2 = 255
  L6_2 = 1
  for L7_2 = L4_2, L5_2, L6_2 do
    L2_2[L7_2] = L7_2
  end
  L4_2 = 1
  L5_2 = L1_2
  L6_2 = 1
  for L7_2 = L4_2, L5_2, L6_2 do
    L8_2 = L7_2 - 1
    L9_2 = string
    L9_2 = L9_2.byte
    L10_2 = A0_2
    L11_2 = L7_2
    L12_2 = L7_2
    L9_2 = L9_2(L10_2, L11_2, L12_2)
    L3_2[L8_2] = L9_2
  end
  L4_2 = 0
  L5_2 = 0
  L6_2 = 255
  L7_2 = 1
  for L8_2 = L5_2, L6_2, L7_2 do
    L9_2 = L2_2[L8_2]
    L9_2 = L4_2 + L9_2
    L10_2 = L8_2 % L1_2
    L10_2 = L3_2[L10_2]
    L9_2 = L9_2 + L10_2
    L4_2 = L9_2 % 256
    L9_2 = L2_2[L4_2]
    L10_2 = L2_2[L8_2]
    L2_2[L4_2] = L10_2
    L2_2[L8_2] = L9_2
  end
  return L2_2
end
KSA = L0_1
function L0_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2
  L2_2 = 0
  L3_2 = 0
  L4_2 = {}
  L5_2 = 1
  L6_2 = A1_2
  L7_2 = 1
  for L8_2 = L5_2, L6_2, L7_2 do
    L9_2 = L2_2 + 1
    L2_2 = L9_2 % 256
    L9_2 = A0_2[L2_2]
    L9_2 = L3_2 + L9_2
    L3_2 = L9_2 % 256
    L9_2 = A0_2[L3_2]
    L10_2 = A0_2[L2_2]
    A0_2[L3_2] = L10_2
    A0_2[L2_2] = L9_2
    L9_2 = A0_2[L2_2]
    L10_2 = A0_2[L3_2]
    L9_2 = L9_2 + L10_2
    L9_2 = L9_2 % 256
    L9_2 = A0_2[L9_2]
    L4_2[L8_2] = L9_2
  end
  return L4_2
end
PRGA = L0_1
function L0_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2
  L2_2 = string
  L2_2 = L2_2.len
  L3_2 = A1_2
  L2_2 = L2_2(L3_2)
  L3_2 = KSA
  L4_2 = A0_2
  L3_2 = L3_2(L4_2)
  L4_2 = PRGA
  L5_2 = L3_2
  L6_2 = L2_2
  L4_2 = L4_2(L5_2, L6_2)
  L5_2 = output
  L6_2 = L4_2
  L7_2 = A1_2
  return L5_2(L6_2, L7_2)
end
RC4 = L0_1
function L0_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2
  L2_2 = string
  L2_2 = L2_2.len
  L3_2 = A1_2
  L2_2 = L2_2(L3_2)
  L3_2 = nil
  L4_2 = {}
  L5_2 = 1
  L6_2 = L2_2
  L7_2 = 1
  for L8_2 = L5_2, L6_2, L7_2 do
    L9_2 = string
    L9_2 = L9_2.byte
    L10_2 = A1_2
    L11_2 = L8_2
    L12_2 = L8_2
    L9_2 = L9_2(L10_2, L11_2, L12_2)
    L3_2 = L9_2
    L9_2 = string
    L9_2 = L9_2.char
    L10_2 = bxor
    L11_2 = A0_2[L8_2]
    L12_2 = L3_2
    L10_2, L11_2, L12_2 = L10_2(L11_2, L12_2)
    L9_2 = L9_2(L10_2, L11_2, L12_2)
    L4_2[L8_2] = L9_2
  end
  L5_2 = table
  L5_2 = L5_2.concat
  L6_2 = L4_2
  return L5_2(L6_2)
end
output = L0_1
L0_1 = {}
function L1_1(A0_2, A1_2)
  local L2_2
  L2_2 = A0_2 + A1_2
  if L2_2 == 2 then
    L2_2 = 1
    if L2_2 then
      goto lbl_8
    end
  end
  L2_2 = 0
  ::lbl_8::
  return L2_2
end
L0_1.cond_and = L1_1
function L1_1(A0_2, A1_2)
  local L2_2
  L2_2 = A0_2 + A1_2
  if L2_2 == 1 then
    L2_2 = 1
    if L2_2 then
      goto lbl_8
    end
  end
  L2_2 = 0
  ::lbl_8::
  return L2_2
end
L0_1.cond_xor = L1_1
function L1_1(A0_2, A1_2)
  local L2_2
  L2_2 = A0_2 + A1_2
  if 0 < L2_2 then
    L2_2 = 1
    if L2_2 then
      goto lbl_8
    end
  end
  L2_2 = 0
  ::lbl_8::
  return L2_2
end
L0_1.cond_or = L1_1
function L1_1(A0_2, A1_2, A2_2)
  local L3_2, L4_2, L5_2, L6_2, L7_2
  if A1_2 < A2_2 then
    L3_2 = A2_2
    A2_2 = A1_2
    A1_2 = L3_2
  end
  L3_2 = 0
  L4_2 = 1
  while A1_2 ~= 0 do
    L5_2 = A1_2 % 2
    r_a = L5_2
    L5_2 = A2_2 % 2
    r_b = L5_2
    L5_2 = L0_1[A0_2]
    L6_2 = r_a
    L7_2 = r_b
    L5_2 = L5_2(L6_2, L7_2)
    L5_2 = L4_2 * L5_2
    L3_2 = L5_2 + L3_2
    L4_2 = L4_2 * 2
    L5_2 = math
    L5_2 = L5_2.modf
    L6_2 = A1_2 / 2
    L5_2 = L5_2(L6_2)
    A1_2 = L5_2
    L5_2 = math
    L5_2 = L5_2.modf
    L6_2 = A2_2 / 2
    L5_2 = L5_2(L6_2)
    A2_2 = L5_2
  end
  return L3_2
end
L0_1.base = L1_1
function L1_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2
  L2_2 = L0_1.base
  L3_2 = "cond_xor"
  L4_2 = A0_2
  L5_2 = A1_2
  return L2_2(L3_2, L4_2, L5_2)
end
bxor = L1_1
function L1_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2
  L2_2 = L0_1.base
  L3_2 = "cond_and"
  L4_2 = A0_2
  L5_2 = A1_2
  return L2_2(L3_2, L4_2, L5_2)
end
band = L1_1
function L1_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2
  L2_2 = L0_1.base
  L3_2 = "cond_or"
  L4_2 = A0_2
  L5_2 = A1_2
  return L2_2(L3_2, L4_2, L5_2)
end
bor = L1_1
L1_1 = print
L2_1 = "Welcome to the world of reverse\n"
L1_1(L2_1)
L1_1 = print
L2_1 = "Now please give me the key : "
L1_1(L2_1)
L1_1 = "RC4KEY"
L2_1 = io
L2_1 = L2_1.read
L3_1 = "*l"
L2_1 = L2_1(L3_1)
L3_1 = string
L3_1 = L3_1.len
L4_1 = L2_1
L3_1 = L3_1(L4_1)
if L3_1 ~= 38 then
  L3_1 = print
  L4_1 = "wrong length"
  L3_1(L4_1)
  L3_1 = os
  L3_1 = L3_1.exit
  L3_1()
end
L3_1 = enclib
L3_1 = L3_1.prepare
L3_1()
L3_1 = enclib
L3_1 = L3_1.encrypt
L4_1 = L2_1
L5_1 = string
L5_1 = L5_1.len
L6_1 = L2_1
L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1 = L5_1(L6_1)
L3_1 = L3_1(L4_1, L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1)
res = L3_1
L3_1 = RC4
L4_1 = L1_1
L5_1 = res
L3_1 = L3_1(L4_1, L5_1)
K = L3_1
L3_1 = {}
t = L3_1
L3_1 = {}
L4_1 = 43
L5_1 = 50
L6_1 = 118
L7_1 = 51
L8_1 = 186
L9_1 = 167
L10_1 = 106
L11_1 = 55
L12_1 = 228
L13_1 = 145
L14_1 = 160
L15_1 = 171
L16_1 = 23
L17_1 = 227
L18_1 = 82
L19_1 = 56
L20_1 = 191
L21_1 = 166
L22_1 = 65
L23_1 = 254
L24_1 = 189
L25_1 = 167
L26_1 = 236
L27_1 = 92
L28_1 = 154
L29_1 = 70
L30_1 = 19
L31_1 = 169
L32_1 = 10
L33_1 = 70
L34_1 = 222
L35_1 = 237
L36_1 = 237
L37_1 = 19
L38_1 = 249
L39_1 = 70
L40_1 = 121
L41_1 = 127
L42_1 = 189
L43_1 = 104
L44_1 = 169
L45_1 = 107
L46_1 = 43
L47_1 = 1
L48_1 = 50
L49_1 = 165
L50_1 = 234
L51_1 = 90
L52_1 = 76
L53_1 = 190
L3_1[1] = L4_1
L3_1[2] = L5_1
L3_1[3] = L6_1
L3_1[4] = L7_1
L3_1[5] = L8_1
L3_1[6] = L9_1
L3_1[7] = L10_1
L3_1[8] = L11_1
L3_1[9] = L12_1
L3_1[10] = L13_1
L3_1[11] = L14_1
L3_1[12] = L15_1
L3_1[13] = L16_1
L3_1[14] = L17_1
L3_1[15] = L18_1
L3_1[16] = L19_1
L3_1[17] = L20_1
L3_1[18] = L21_1
L3_1[19] = L22_1
L3_1[20] = L23_1
L3_1[21] = L24_1
L3_1[22] = L25_1
L3_1[23] = L26_1
L3_1[24] = L27_1
L3_1[25] = L28_1
L3_1[26] = L29_1
L3_1[27] = L30_1
L3_1[28] = L31_1
L3_1[29] = L32_1
L3_1[30] = L33_1
L3_1[31] = L34_1
L3_1[32] = L35_1
L3_1[33] = L36_1
L3_1[34] = L37_1
L3_1[35] = L38_1
L3_1[36] = L39_1
L3_1[37] = L40_1
L3_1[38] = L41_1
L3_1[39] = L42_1
L3_1[40] = L43_1
L3_1[41] = L44_1
L3_1[42] = L45_1
L3_1[43] = L46_1
L3_1[44] = L47_1
L3_1[45] = L48_1
L3_1[46] = L49_1
L3_1[47] = L50_1
L3_1[48] = L51_1
L3_1[49] = L52_1
L3_1[50] = L53_1
L4_1 = 239
L5_1 = 227
L3_1[51] = L4_1
L3_1[52] = L5_1
flag = L3_1
L3_1 = 1
L4_1 = string
L4_1 = L4_1.len
L5_1 = K
L4_1 = L4_1(L5_1)
L5_1 = 1
for L6_1 = L3_1, L4_1, L5_1 do
  L7_1 = table
  L7_1 = L7_1.insert
  L8_1 = t
  L9_1 = string
  L9_1 = L9_1.byte
  L10_1 = string
  L10_1 = L10_1.sub
  L11_1 = K
  L12_1 = L6_1
  L13_1 = L6_1
  L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1 = L10_1(L11_1, L12_1, L13_1)
  L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1 = L9_1(L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1)
  L7_1(L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1)
end
L3_1 = 1
L4_1 = string
L4_1 = L4_1.len
L5_1 = K
L4_1 = L4_1(L5_1)
L5_1 = 1
for L6_1 = L3_1, L4_1, L5_1 do
  L7_1 = t
  L7_1 = L7_1[L6_1]
  L8_1 = flag
  L8_1 = L8_1[L6_1]
  if L7_1 ~= L8_1 then
    L7_1 = print
    L8_1 = "wrong"
    L7_1(L8_1)
    L7_1 = os
    L7_1 = L7_1.exit
    L7_1()
  end
end
L3_1 = print
L4_1 = "correct!"
L3_1(L4_1)

代码虽然不好看,但是好歹能看。

逻辑分析下来,第一层加密在enclib.encrypt,回IDA康康

https://cdn.shi1011.cn/2021/08/1c03c2b2a328801390681ce9328c7bce.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5
// local variable allocation has failed, the output may be wrong!
int __cdecl sub_4A9110(int a1)
{
  _DWORD *v1; // edi
  int v2; // eax
  int *v3; // ecx
  double v4; // xmm0_8
  int v5; // ecx
  int v6; // esi
  int v7; // ebx
  const char *v8; // ecx
  unsigned int v9; // eax
  int v10; // edx
  const char *v11; // esi
  int v12; // ebx
  int v13; // edi
  unsigned int v14; // ecx
  unsigned int v15; // edx
  int v16; // eax
  unsigned int v17; // ecx
  int v18; // ebx
  int v19; // eax
  int *v20; // ecx
  int v21; // eax
  int v23; // [esp+4h] [ebp-1Ch]
  int v24; // [esp+10h] [ebp-10h]
  const char *v25; // [esp+14h] [ebp-Ch]
  int v26; // [esp+18h] [ebp-8h]
  double var8_4; // [esp+1Ch] [ebp-4h] OVERLAPPED BYREF

  v1 = (_DWORD *)a1;
  lua_pushnil(0);
  v24 = v2;
  if ( !v2 )
    lua_pushvalue((lua_State *)4, v23);
  v3 = &dword_4DCDA0;
  if ( (unsigned int)(**(_DWORD **)(a1 + 20) + 32) < *(_DWORD *)(a1 + 12) )
    v3 = (int *)(**(_DWORD **)(a1 + 20) + 32);
  if ( v3[2] == 3 )
  {
    v4 = *(double *)v3;
  }
  else
  {
    if ( !luaV_tonumber_(v3, &var8_4) )
      lua_pushvalue((lua_State *)3, v23);
    v4 = var8_4;
  }
  v5 = (int)v4 / 3;
  v6 = 4 * v5;
  v7 = (int)v4 % 3;
  if ( v7 )
    v6 = 4 * v5 + 4;
  v8 = (const char *)malloc(__CFADD__(v6, 1) ? -1 : v6 + 1);
  v9 = v6 - 2;
  v25 = v8;
  v10 = 0;
  v8[v6] = 0;
  if ( v6 - 2 > 0 )
  {
    v11 = v8 + 2;
    v12 = v24 + 2;
    v13 = (v9 >> 2) + 1;
    LODWORD(var8_4) = 4 * v13;
    do
    {
      v14 = *(unsigned __int8 *)(v12 - 2);
      v12 += 3;
      v15 = *(unsigned __int8 *)(v12 - 4);
      v11 += 4;
      *((_BYTE *)v11 - 6) = aAbcdefghijklmn[v14 >> 2];
      v16 = (16 * (v14 & 3)) | (v15 >> 4);
      v17 = *(unsigned __int8 *)(v12 - 3);
      *((_BYTE *)v11 - 5) = aAbcdefghijklmn[v16];
      *((_BYTE *)v11 - 4) = aAbcdefghijklmn[(4 * (v15 & 0xF)) | (v17 >> 6)];
      *((_BYTE *)v11 - 3) = aAbcdefghijklmn[v17 & 0x3F];
      --v13;
    }
    while ( v13 );
    v1 = (_DWORD *)a1;
    v8 = v25;
    v26 = (int)v4 % 3;
    v10 = LODWORD(var8_4);
    v7 = v26;
  }
  v18 = v7 - 1;
  if ( v18 )
  {
    if ( v18 == 1 )
      v8[v10 - 1] = '=';
  }
  else
  {
    *(_WORD *)&v8[v10 - 2] = 15677;
  }
  if ( v8 )
  {
    v19 = T_000_new_localvarliteral_((int)v1, v8);
    v20 = (int *)v1[3];
    *v20 = v19;
    v20[2] = *(unsigned __int8 *)(v19 + 4) | 0x40;
  }
  else
  {
    *(_DWORD *)(v1[3] + 8) = 0;
  }
  v21 = v1[4];
  v1[3] += 16;
  if ( *(int *)(v21 + 12) > 0 )
    luaC_step(v1);
  return 1;
}

明显的base64

顺便看下prepare

int sub_4A90D0()
{
  int v0; // esi
  char *v1; // eax
  char v2; // dl

  v0 = 0;
  v1 = &aAbcdefghijklmn[63];
  do
  {
    v2 = byte_50AA8F[++v0];
    byte_50AA8F[v0] = *v1;
    *v1-- = v2;
  }
  while ( (int)v1 > (int)&aAbcdefghijklmn[31] );
  return 1;
}

逆了一下码表

看第二层,RC4,对称加密,密钥为RC4KEY直接抄代码运行了,省的分析算法,去看有没有魔改

然而密钥是错的 = =,ida分析一下会发现,密钥变成了Good!!

https://cdn.shi1011.cn/2021/08/530b89278ae642ff382be920de7d88b1.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5
function KSA(key)
    local key_len = string.len(key)
    local S = {}
    local key_byte = {}

    for i = 0, 255 do
        S[i] = i
    end

    for i = 1, key_len do
        key_byte[i-1] = string.byte(key, i, i)
    end

    local j = 0
    for i = 0, 255 do
        j = (j + S[i] + key_byte[i % key_len]) % 256
        S[i], S[j] = S[j], S[i]
    end
    return S
end

function PRGA(S, text_len)
    local i = 0
    local j = 0
    local K = {}

    for n = 1, text_len do

        i = (i + 1) % 256
        j = (j + S[i]) % 256

        S[i], S[j] = S[j], S[i]
        K[n] = S[(S[i] + S[j]) % 256]
    end
    return K
end

function RC4(key, text)
    local text_len = string.len(text)

    local S = KSA(key)        
    local K = PRGA(S, text_len) 
    return output(K, text)
end

function output(S, text)
    local len = string.len(text)
    local c = nil
    local res = {}
    for i = 1, len do
        c = string.byte(text, i, i)
        res[i] = string.char(bxor(S[i], c))
    end
    return table.concat(res)
end

local bit_op = {}
function bit_op.cond_and(r_a, r_b)
    return (r_a + r_b == 2) and 1 or 0
end

function bit_op.cond_xor(r_a, r_b)
    return (r_a + r_b == 1) and 1 or 0
end

function bit_op.cond_or(r_a, r_b)
    return (r_a + r_b > 0) and 1 or 0
end

function bit_op.base(op_cond, a, b)
    -- bit operation
    if a < b then
        a, b = b, a
    end
    local res = 0
    local shift = 1
    while a ~= 0 do
        r_a = a % 2
        r_b = b % 2
   
        res = shift * bit_op[op_cond](r_a, r_b) + res 
        shift = shift * 2

        a = math.modf(a / 2)
        b = math.modf(b / 2)
    end
    return res
end

function bxor(a, b)
    return bit_op.base('cond_xor', a, b)
end

function band(a, b)
    return bit_op.base('cond_and', a, b)
end

function bor(a, b)
    return bit_op.base('cond_or', a, b)
end


local L0_1, L1_1, L2_1, L3_1, L4_1, L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1

L3_1 = {}
L4_1 = 43
L5_1 = 50
L6_1 = 118
L7_1 = 51
L8_1 = 186
L9_1 = 167
L10_1 = 106
L11_1 = 55
L12_1 = 228
L13_1 = 145
L14_1 = 160
L15_1 = 171
L16_1 = 23
L17_1 = 227
L18_1 = 82
L19_1 = 56
L20_1 = 191
L21_1 = 166
L22_1 = 65
L23_1 = 254
L24_1 = 189
L25_1 = 167
L26_1 = 236
L27_1 = 92
L28_1 = 154
L29_1 = 70
L30_1 = 19
L31_1 = 169
L32_1 = 10
L33_1 = 70
L34_1 = 222
L35_1 = 237
L36_1 = 237
L37_1 = 19
L38_1 = 249
L39_1 = 70
L40_1 = 121
L41_1 = 127
L42_1 = 189
L43_1 = 104
L44_1 = 169
L45_1 = 107
L46_1 = 43
L47_1 = 1
L48_1 = 50
L49_1 = 165
L50_1 = 234
L51_1 = 90
L52_1 = 76
L53_1 = 190
L3_1[1] = L4_1
L3_1[2] = L5_1
L3_1[3] = L6_1
L3_1[4] = L7_1
L3_1[5] = L8_1
L3_1[6] = L9_1
L3_1[7] = L10_1
L3_1[8] = L11_1
L3_1[9] = L12_1
L3_1[10] = L13_1
L3_1[11] = L14_1
L3_1[12] = L15_1
L3_1[13] = L16_1
L3_1[14] = L17_1
L3_1[15] = L18_1
L3_1[16] = L19_1
L3_1[17] = L20_1
L3_1[18] = L21_1
L3_1[19] = L22_1
L3_1[20] = L23_1
L3_1[21] = L24_1
L3_1[22] = L25_1
L3_1[23] = L26_1
L3_1[24] = L27_1
L3_1[25] = L28_1
L3_1[26] = L29_1
L3_1[27] = L30_1
L3_1[28] = L31_1
L3_1[29] = L32_1
L3_1[30] = L33_1
L3_1[31] = L34_1
L3_1[32] = L35_1
L3_1[33] = L36_1
L3_1[34] = L37_1
L3_1[35] = L38_1
L3_1[36] = L39_1
L3_1[37] = L40_1
L3_1[38] = L41_1
L3_1[39] = L42_1
L3_1[40] = L43_1
L3_1[41] = L44_1
L3_1[42] = L45_1
L3_1[43] = L46_1
L3_1[44] = L47_1
L3_1[45] = L48_1
L3_1[46] = L49_1
L3_1[47] = L50_1
L3_1[48] = L51_1
L3_1[49] = L52_1
L3_1[50] = L53_1
L4_1 = 239
L5_1 = 227
L3_1[51] = L4_1
L3_1[52] = L5_1
flag = L3_1


local function bin2hex(s)
    s=string.gsub(s,"(.)",function (x) return string.format("%02X",string.byte(x)) end)
    return s
end
 
local h2b = {
    ["0"] = 0,
    ["1"] = 1,
    ["2"] = 2,
    ["3"] = 3,
    ["4"] = 4,
    ["5"] = 5,
    ["6"] = 6,
    ["7"] = 7,
    ["8"] = 8,
    ["9"] = 9,
    ["A"] = 10,
    ["B"] = 11,
    ["C"] = 12,
    ["D"] = 13,
    ["E"] = 14,
    ["F"] = 15
}
 
local function hex2bin( hexstr )
    local s = string.gsub(hexstr, "(.)(.)%s", function ( h, l )
         return string.char(h2b[h]*16+h2b[l])
    end)
    return s
end



text = ""
for i = 1, 52 do
        text = text .. string.char(flag[i])
end

key = "Good!!"
K = RC4(key, text)
print (bin2hex(K))

再换码表base64解码完事

后记

后期验证了一下,用lua跑出对比密文的hex解码就行

https://cdn.shi1011.cn/2021/08/5e0d4e6ad8a197d09eae2f435a296d92.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

Misc

funny_maze

nc连接,就是走迷宫,计算要走的步数,四轮,一轮比一轮多

写个寻路算法,然后直接pwntools上手

为了快点拿到flag,脚本写的我自己都不忍直视……直接手动跑了最后一次(不过算法写法还是ok的)

from pwn import *
from six import b

class maze:
    def __init__(self, maze, size, sx, sy, ex, ey):
        self.end = [ey, ex]
        self.size = size
        self.route_stack = [[sy, sx]]
        self.route_history = [[sy, sx]]
        self.lo = [sy, sx]

        self.source = maze

    def up(self, location):
    
        if location[1] == 0:
            return False
        else:
            new_location = [location[0], location[1] - 1]
            # 
            if new_location in self.route_history:
                return False
            # 
            elif self.source[new_location[0]][new_location[1]] == 1:
                return False
            else:
                self.route_stack.append(new_location)
                self.route_history.append(new_location)
                return True

    def down(self, location):
        if location[1] == self.size - 1:
            return False
        else:
            new_location = [location[0], location[1] + 1]
            if new_location in self.route_history:
                return False
            elif self.source[new_location[0]][new_location[1]] == 1:
                return False
            else:
                self.route_stack.append(new_location)
                self.route_history.append(new_location)
                return True

    def left(self, location):
        if location[0] == 0:
            return False
        else:
            new_location = [location[0] - 1, location[1]]
            if new_location in self.route_history:
                return False
            elif self.source[new_location[0]][new_location[1]] == 1:
                return False
            else:
                self.route_stack.append(new_location)
                self.route_history.append(new_location)
                return True

    def right(self, location):
        if location[0] == self.size - 1:
            return False
        else:
            new_location = [location[0] + 1, location[1]]
            if new_location in self.route_history:
                return False
            elif self.source[new_location[0]][new_location[1]] == 1:
                return False
            else:
                self.route_stack.append(new_location)
                self.route_history.append(new_location)
                return True

    def findpath(self):
        while self.route_stack[-1] != self.end:
            if self.up(self.lo):
                self.lo = self.route_stack[-1]
                continue
            if self.down(self.lo):
                self.lo = self.route_stack[-1]
                continue
            if self.left(self.lo):
                self.lo = self.route_stack[-1]
                continue
            if self.right(self.lo):
                self.lo = self.route_stack[-1]
                continue
            self.route_stack.pop()
            self.lo = self.route_stack[-1]

        return self.route_stack


r = remote("node4.buuoj.cn", 25619)


r.sendline(b"1")

t2 = "Please enter your answer:"
data = r.recvuntil(t2)
t = "3.Introduction to this game\n"
mazeStr = data[data.find(t) + len(t):-len(t2)]

for _ in range(4):
    mazes = []
    startx = starty = 0
    endx = endy = 0
    
    for j, line in enumerate(mazeStr.splitlines()):
        tline = [1] * len(line)
        for m, i in enumerate(line):
            if i == "#":
                tline[m] = 1
            elif i == " ":
                tline[m] = 0
            elif i == "S":
                startx = m
                starty = j
                tline[m] = 0
            elif i == "E":
                endx = m
                endy = j
                tline[m] = 0
        mazes.append(tline)


    lesn = len(mazes)
    m = maze(mazes, lesn, startx, starty, endx, endy).findpath()
    print(m)
    
    if _ == 3:
        print(len(m))
        r.interactive()
    
    r.sendline(str(len(m)).encode())
    
    tt = b"answer:"
    data = r.recvuntil(tt)
    print(data)
    sleep(1)
    t = "next level!\n"
    mazeStr = data[data.find(t) + len(t):-len(tt)]
   
本文链接:https://blog.shi1011.cn/ctf/1530
本文采用 CC BY-NC-SA 4.0 Unported 协议进行许可
# # # #
首页      ctf      2021DASCTF实战精英夏令营暨DASCTF July X CBCTF 4th

Mas0n

文章作者

发表回复

textsms
account_circle
email

翻车鱼

2021DASCTF实战精英夏令营暨DASCTF July X CBCTF 4th
标题好长= = Rev shellcode 拿到题目 目录结构 . ├── main.bat ├── part1.exe ├── part2.bin └── part3.exe cat main.bat set /p FLAG=please input your flag: sta…
扫描二维码继续阅读
2021-08-02