moectf-re WP

IntroducingRe

Pull the downloaded file into IDA, f5 run it:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+17h] [ebp-19h]
  int v5; // [esp+1Bh] [ebp-15h]
  int v6; // [esp+1Fh] [ebp-11h]
  int v7; // [esp+23h] [ebp-Dh]
  int v8; // [esp+27h] [ebp-9h]
  int v9; // [esp+2Bh] [ebp-5h]
  char v10; // [esp+2Fh] [ebp-1h]
​
  sub_401F10();
  puts("Welcome to the MoeCTF!");
  v4 = 1667592045;
  v5 = 1148937844;
  v6 = 1868128048;
  v7 = 845897589;
  v8 = 1230993263;
  v9 = 2101297476;
  v10 = 0;
  sub_401500((char *)&v4);
  return system("pause");
}

The (char *) v4 consideration should be the start of a series of end v10 string, using a shortcut key 'R' to be converted into characters, i.e., to obtain flag: {? D0_You_k2ow_IDA} moectf

MoeRe

The files into IDA, f5:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  int result; // eax
  int j; // [rsp+10h] [rbp-A0h]
  int i; // [rsp+14h] [rbp-9Ch]
  int v7; // [rsp+18h] [rbp-98h]
  __int64 v8; // [rsp+20h] [rbp-90h]
  char v9[104]; // [rsp+40h] [rbp-70h]
  __int64 v10; // [rsp+A8h] [rbp-8h]
​
  scanf("%s", v9, envp);
  v3 = strlen(v9);
  v7 = v3;
  strcpy((char *)&v8, "abcdefghijklmnopqrstuvwxyz");
  for ( i = 0; i < v3; ++i )
    v9[i] ^= *((_BYTE *)&v8 + i % 26);
  for ( j = 0; j < v7; ++j )
    printf("%d,", (unsigned int)v9[j]);
  result = 0;
  if ( __stack_chk_guard == v10 )
    result = 0;
  return result;
}

Means: flag character (V9) respectively with 26 letters (V8) XOR operation, wherein:

V9 [ I ] ^ =  * (( _BYTE  * ) & v8  +  I  %  26 is ); // get the first byte from the beginning v8, and + i% 26, i.e., the position corresponding to the letters of the XOR

This result is the title of a long list of output results:

 

So try to write the script, as follows:

Import numpy 
# write file: 
INF1 the INPUT = ( "" )      
 # operation results in the title of 
inf2 = inf1.split ( ' , ' )
 # to read string ',' separated and stored in the list inf2 
file1 = Open ( " C: /Python27/Myprogrammes/test2.txt " , " W " ) 
N = len (INF2)
 for I in Range (N): 
file1.write (STR (INF2 [I])) 
file1.write ( ' \ n- ' )
 # write the file according to a data format of each row 
file1.close () 
# read file:
= Open File (R & lt " C: /Python27/Myprogrammes/test2.txt " ) 
NUM = []
 for Line in File: 
    Line = line.strip ( ' \ n ' )   
     # The \ n remove 
    num.append (line.split ())
     # data added to each row of num list 
File.close () 
# processing data read 
num = numpy.array (num, DTYPE = int)
 # the list into a num Array 
str1 = " ABCDEFGHIJKLMNOPQRSTUVWXYZ " 
n- = len (NUM)     
In Flag = []
 for i in range(n):
flag.append(num[i]^ord(str1[i]))
strlist = list(flag)
for i in range(n):
strlist[i]=chr(flag[i])
print("".join(strlist))
#输出flag

Run obtain flag: moectf {Kn0wing_R3v3rs3_from_x0r_and_1da}

.pyc

Use of anti-compiled online site (there are many sites failed to display decompile, temporarily I do not know the reason) to obtain:

from binascii import b2a_hex
from base64 import b32encode
x = input
y = print
if b2a_hex(b32encode(x().encode())).decode() == '4e5658574b5933554d5a3558413452544d4d59473234444a4e525557345a5a4e4b4234574758334447525846364d44514f51595732324c324d55575647344254474e5348323d3d3d':
    y('congrats')

The flag means that the first base32 encoded, then each character becomes hexadecimal form its corresponding ASCII code. Thus, the first hexadecimal to ASCII code corresponding to the text, can be re-decoded base32. To give flag: moectf {pr3c0mpiling-Pyc_c4n_0pt1mize- Sp33d}

Added: family encodes base again read it again, again summarized:

16=2^4 32=2^5 64=2^6

∴base16 four bytes per a divided, corresponding to 0-9, AF

base32是每5个字节一划分,对应2-7,A-Z,用0和=凑够成编码后的字符长度是八的整数倍

base64是每6个字节一划分,对应0-9,A-Z,a-z,+,/,用0和=凑够成编码后的字符长度是四的整数倍

EasyShell

由题目已经知道是upx加壳,下载了UpxUnpacker,但尝试无果,放入kali linux,输入

upx -d upx.exe

再拖入IDA,得到flag:moectf{upx_1s_a_K1nd_0F_sh21L}

#EasyDebugger

题目明显说明这道题应该用到调试器,于是下载windbg,配置symbol,开调试直接蹦出flag : moectf{Debuger_1s_@_Go04_tOoL_4_r2vers2}

#EasyGo

题目提示这道题的点在于Go语言的入口点,

资料如下:

Go 程序是通过 package 来组织的。

只有 package 名称为 main 的包可以包含 main 函数。

一个可执行程序有且仅有一个 main 包。

通过 import 关键字来导入其他非 main 包。

所以入口点为main_main函数,f5运行一下:

fmt_Fscanln(a1, a2, (__int64)&v28, (__int64)&unk_4AAF60, v11, v12, (__int64)&go_itab__os_File_io_Reader, os_Stdin);
  if ( *v24 == 1107LL )
  {
    runtime_convTstring(a1, a2, v13, v14, v15, v16, (__int64)&unk_4D954E, 34LL);
    *(_QWORD *)&v27 = &unk_4B0720;
    *((_QWORD *)&v27 + 1) = &v28;
    fmt_Fprintln(
      a1,
      a2,
      v17,
      (__int64)&go_itab__os_File_io_Writer,
      v18,
      v19,
      (__int64)&go_itab__os_File_io_Writer,
      os_Stdout);
  }

直接跟进unk_4D954E,找到flag: moectf{G0_1Anguage_1s_1nT3r3st1ng}

#EasyJava

拿到题目,利用jd-gui反汇编class文件(BOX),得到关键代码:

 
public static boolean CHECK(int input)
  {
    if ((input > 10000000) && (input < 99999999))
    {
      int v7 = 1;
      int v8 = 10000000;
      int v3 = 1;
      if ((Math.abs(input / 1000 % 100 - 80) == 3) && (input % 1000 % 927 == 0))
      {
        int v5 = 0;
        while (v5 < 4)
        {
          if (input / v7 % 10 != input / v8 % 10)
          {
            v3 = 0;
            break;
          }
          v7 *= 10;
          v8 /= 10;
          v5++;
        }
        if (v3 != 1) {
          return false;
        }
        if (v3 == 1) {
          return true;
        }
      }
    }
    return false;
  }
 

条件:

(Math.abs(input / 1000 % 100 - 80) == 3) && (input % 1000 % 927 == 0)

表示输入的中间两位是83或77,最后三位是927;

条件:

while (v5 < 4)
        {
          if (input / v7 % 10 != input / v8 % 10)
          {
            v3 = 0;
            break;
          }
          v7 *= 10;
          v8 /= 10;
          v5++;
        }

判断输入是否是回文字符串,即:输入必须满足72977927,最后判断输出flag的代码:

 if (e.getSource() == this.bt) {
      if (CHECK(Integer.parseInt(this.a))) {
        this.tx.setText("moectf{" + (char)(Integer.parseInt(this.a) / 1000000) + (char)(Integer.parseInt(this.a) / 10000 % 100) + (char)(Integer.parseInt(this.a) / 100 % 100) + "_he}");
      } else {
        this.tx.setText("clear and try again!");
      }
    }

意思是将该整数两位两位拆开转成字符,其中27对应Esc退出,所以得到flag : moectf{Hao_he}

#Mine Sweep

先找到main函数,

输入1执行程序,跟进下面这个函数,找到关键,发现显示的是字符串success:

找到调用的地方:

 

可以看出是一个条件分支,将上面的jz改成jnz保存再执行程序即可得到flag:moectf{G00d_Min3_5w3eper}

#EasyRe

题目描述:You can decode the string or AntiAntiDebug(: Enjoy it~

打开题目,无壳ELF文件,拖入IDA,找到mian函数,

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  __int64 v4; // [rsp+10h] [rbp-30h]
  __int64 v5; // [rsp+18h] [rbp-28h]
  __int64 v6; // [rsp+20h] [rbp-20h]
  int v7; // [rsp+28h] [rbp-18h]
  __int16 v8; // [rsp+2Ch] [rbp-14h]
  char v9; // [rsp+2Eh] [rbp-12h]
  int v10; // [rsp+38h] [rbp-8h]
  int v11; // [rsp+3Ch] [rbp-4h]
​
  v11 = 0;
  sub_4011E0();
  v10 = 1;
  v4 = 0x3A362B392E282274LL;
  v5 = 0x9123F393E123A7DLL;
  v6 = 0x3E7C127E297D2E79LL;
  v7 = 0x3E792812;
  v8 = 12340;
  v9 = 0x4D;
  printf(&byte_4040B0);
  sub_401270(&v4);
  sub_4012A0();
  return 0LL;
}

进入

__int64 sub_401360()
{
  bool v0; // ST3B_1
  bool v1; // ST2F_1
  bool v2; // ST23_1
  bool v3; // ST17_1
  __int64 result; // rax
  bool v5; // ST0B_1
  unsigned int v6; // [rsp+8h] [rbp-34h]
  unsigned int v7; // [rsp+14h] [rbp-28h]
  unsigned int v8; // [rsp+20h] [rbp-1Ch]
  unsigned int v9; // [rsp+2Ch] [rbp-10h]
  unsigned int v10; // [rsp+38h] [rbp-4h]
​
  v10 = 0;
  do
  {
    *(&format + (signed int)v10) ^= 0x1Au;
    v0 = v10++ < 0x1D;
  }
  while ( v0 );
  v9 = 0;
  do
  {
    *(&byte_40406E + (signed int)v9) ^= 0x17u;
    v1 = v9++ < 2;
  }
  while ( v1 );
  v8 = 0;
  do
  {
    byte_404080[v8] ^= 0x4Du;
    v2 = v8++ < 0x1E;
  }
  while ( v2 );
  v7 = 0;
  do
  {
    *(&byte_40409F + (signed int)v7) ^= 0x1Au;
    v3 = v7++ < 4;
  }
  while ( v3 );
  v6 = 0;
  do
  {
    *(&byte_4040B0 + (signed int)v6) ^= 0xBEu;
    result = v6 - 23;
    v5 = v6++ < 0x17;
  }
  while ( v5 );
  return result;
}

逐个追踪,发现byte_404080中存储的数据和主函数的相同,于是写exp实现一下,

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
​
typedef unsigned char Byte;
int main(int argc, char** argv) {
int v8=0;
long long int a=0x3A362B392E282274LL;
char t;
do
{
t=(char)(*((Byte *)&a+v8)^0x4D);
cout<<t;
}while(v8++<7);
return 0;
}

跑出:9oectf{w0w_str_D4c0d3_1s_e4sy},把9改成m,得到flag.

补充:在unsigned char 为1个字节长度,unsigned int 为4个字节,在我的电脑中long long int是8个字节长度来储存整型,本题中以字节(两个十六进制数位)为单位逐个亦或,且exp中最多八个字节长度,否则数值溢出。

注:以上带有#标记的为赛后复现,tcl,tcl......

Guess you like

Origin www.cnblogs.com/Theffth-blog/p/12231708.html