攻防世界-notsequence

看见x*(x+1)/2应联想起杨辉三角

ida进入主函数

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

  memset(&unk_8049BE0, 0, 0x4000u);
  puts("input raw_flag please:");
  v3 = &unk_8049BE0;
  do
  {
    v0 = v3++;
    scanf("%d", v0);
  }
  while ( *(v3 - 1) );
  v2 = sub_80486CD(&unk_8049BE0);
  if ( v2 == -1 )
  {
    printf("check1 not pass");
    system("pause");
  }
  if ( (unsigned __int8)sub_8048783(&unk_8049BE0, v2) != 1 )
  {
    printf("check2 not pass!");
    exit(0);
  }
  if ( v2 == 20 )
  {
    puts("Congratulations! fl4g is :\nRCTF{md5(/*what you input without space or \\n~*/)}");
    exit(0);
  }
  return 0;
}

看第一个check函数

int __cdecl sub_80486CD(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);
    if ( 1 << v5 != v3 )                     //2^v5==v3
      return -1;
    ++v5;
  }
  return v5;
}

看第二个check函数

int __cdecl sub_8048783(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;
}

经过这2个函数判断, 就能知道是否是杨辉三角形了. 把前20行的数据经过md5加密就是flag.
Python脚本

def createL(l):
    L = [1]
    for x in range(1, len(l)):
        L.append(l[x] + l[x-1])
    L.append(1)
    return L

def printL(L, W):
    s = ""
    for x in L:
        s += str(x) + " "
    print(s.center(W))

def str_(s, L):
    for x in L:
        s += str(x)
    return s

import hashlib
L = [1]
s = ""
row = int(input("请输入行数: "))
width =row* 6
for x in range(row):
    printL(L, width)
    s = str_(s, L)
    L = createL(L)
print(s)
m = hashlib.md5(s.encode()).hexdigest()
print("md5加密后:%s" % m)

C语言脚本

#include <stdio.h>
#include <stdlib.h> 
#include <string.h> 

int *creat(int *L, int lenth)
{
	int i = 0;
	int *p = (int *)malloc(sizeof(int)*(lenth+1));
	
	p[0] = 1;
	for(i = 1; i < lenth; i++)
	p[i] = L[i-1] + L[i];
	
	p[lenth] = 1;
	
	return p;  
}

void print(int *L, int blank_l, int lenth)
{
	int i = 0;
	
	for(i = 0; i < blank_l; i++)
	printf("  ");
	
	for(i = 0; i < lenth; i++)
	printf("%4d", L[i]); 
	
	putchar(10);
}

char *translate(int *L, int lenth)
{
	int i = 0;
	char *p = (char *)malloc(sizeof(char)*100), temp[100] = {0};
	
	memset(p, 0, sizeof(char));
	for(i = 0; i < lenth; i++)
	{
		sprintf(temp, "%d", L[i]);
		strcat(p, temp); 
	} 
	
	return p;
} 

int main(void)
{
	int n = 0, i = 0, *p = NULL;
	char a[1000] = {0}; 
	
	printf("请输入行数: ");
	scanf("%d", &n);
	
	for(i = 0; i < n; i++)
	{
		p = creat(p, i);
		print(p, n-i, i+1);
		strcat(a, (char *)translate(p, i+1));
	} 
	
	printf("\n所有数值组成的字符串为: %s", a); 
	return 0;  
} 

到md5在线网站加密一下,得到密文,包裹上RCTF{},得到flag:RCTF{37894beff1c632010dd6d524aa9604db}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值