XCTF-RE-notsequence-杨辉三角

CTF · 03-21 · 78 人浏览

1.查壳

Pasted image 20231221152908.png
ELF32 无壳
kali中运行
Pasted image 20231221152935.png

2.IDA静态分析

(1)main

int __cdecl main()
{
  _DWORD *v0; // eax
  int v2; // [esp+14h] [ebp-Ch]
  _DWORD *v3; // [esp+1Ch] [ebp-4h]

  memset(&input, 0, 0x4000u);
  puts("input raw_flag please:");
  v3 = &input;
  do
  {
    v0 = v3++;
    scanf("%d", v0);
  }
  while ( *(v3 - 1) );
  v2 = check1((int)&input);
  if ( v2 == -1 )
  {
    printf("check1 not pass");
    system("pause");
  }
  if ( (unsigned __int8)check2(&input, v2) != 1 )
  {
    printf("check2 not pass!");
    exit(0);
  }
  if ( v2 == 20 )                               // v2=20
  {
    puts("Congratulations! fl4g is :\nRCTF{md5(/*what you input without space or \\n~*/)}");// flag格式提示:去掉空格和换行符还有~*后md5加密
    exit(0);
  }
  return 0;
}

程序逻辑分析:
1.提示后用户进行输入,先对输入执行check1验证并返回v2。
2.check1通过后再进行check2验证,check2的参数为输入和v2.
3.check2通过后,判断v2是否等于20,,若等于20,则输出flag格式提示。
flag格式为:RCTF{}包裹,去掉空格、换行符以及~和*的md5加密值。

(2)check1

int __cdecl check1(int a1)
{
  int j; // [esp+0h] [ebp-14h]
  int v3; // [esp+4h] [ebp-10h]
  int i; // [esp+8h] [ebp-Ch]
  int v5; // [esp+Ch] [ebp-8h]

  v5 = 0;
  for ( i = 0; i <= 1024 && *(_DWORD *)(4 * i + a1); i = v5 * (v5 + 1) / 2 )// i=0,1,3,6,10,15...
  {
    v3 = 0;
    for ( j = 0; j <= v5; ++j )
      v3 += *(_DWORD *)(4 * (j + i) + a1);      // v3等于从a1[i]起(包括a1[i])的连续(v5+1)(因为j从0到v5)个元素相加
    if ( 1 << v5 != v3 )                        // v5左移1位要等于v3,即v5*2=v3
      return -1;
    ++v5;
  }
  return v5;                                    // 返回值为v5
}

分析前面几次循环:
v5=0,i=1:
v3=a1[0]

v5=1,i=1:
v3=a1[1]+a1[2]

v5=2,i=3:
v3=a1[3]+a1[4]+a1[5]

v5=3,i=6:
v3=a1[6]+a1[7]+a1[8]+a1[9]

v3在每次循环中的值为:
a1[0]
a1[1] + a1[2]
a1[3] + a1[4] + a1[5]
a1[6] + a1[7] + a1[8] + a1[9]

最后判断v5左移一位等于v3

(3)check2

int __cdecl check2(int a1, int a2)
{
  int v3; // [esp+10h] [ebp-10h]
  int v4; // [esp+14h] [ebp-Ch]
  int i; // [esp+18h] [ebp-8h]
  int v6; // [esp+1Ch] [ebp-4h]

  v6 = 0;
  for ( i = 1; i < a2; ++i )
  {
    v4 = 0;
    v3 = i - 1;
    if ( !*(_DWORD *)(4 * i + a1) )
      return 0;
    while ( a2 - 1 > v3 )                       
    {
      v4 += *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + v6) + a1);
      ++v3;
    }
    if ( *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + i) + a1) != v4 )
      return 0;
    ++v6;
  }
  return 1;
}

代码逻辑有点难以理解,查看WP后发现其为杨辉三角

3.解题

main中的v2是要求我们输入的杨辉三角的层数为20
flag中的值就是将20层杨辉三角所有元素按顺序连在一起后,再进行md5加密的结果

python脚本如下:

import hashlib  
a = []  
  
for i in range(0, 20):  
    b = []  
    for j in range(0, i + 1):  
        b.append(1)  
    a.append(b)  
  
print(a)  
for i in range(1, 20):  
    for j in range(1, i):  
        a[i][j] = a[i - 1][j] + a[i - 1][j - 1]  
  
print(a)  
  
flag = ""  
for i in range(0, len(a)):  
    for j in range(0, len(a[i])):  
        flag += str(a[i][j])  
  
f = hashlib.md5(flag.encode()).hexdigest()  
print("RCTF{" + f +"}")

运行结果:

Pasted image 20231221155027.png
flag为:RCTF{37894beff1c632010dd6d524aa9604db}

CTF RE XCTF 杨辉三角
Theme Jasmine by Kent Liao