UNCTF2021-reverse-部分wp

比赛网址

https://ctf.unctf.com/#/match

官方wp

2021UNCTF

ezlogin

简单签到题,IDA32位打开,flag就在login()中

在这里插入图片描述

跟进查看

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



```c
int login(void)
{
  double v0; // st7
  signed int v1; // eax
  signed int v2; // ecx
  int v3; // edi
  int v4; // eax
  int v5; // ebx
  int v6; // edi
  char *v7; // edx
  int i; // ecx
  char v9; // al
  float v11; // [esp+10h] [ebp-C8h]
  float v12; // [esp+24h] [ebp-B4h]
  double v13; // [esp+28h] [ebp-B0h]
  double v14; // [esp+30h] [ebp-A8h]
  float v15; // [esp+3Ch] [ebp-9Ch]
  char Text[16]; // [esp+40h] [ebp-98h] BYREF
  char v17[44]; // [esp+50h] [ebp-88h] BYREF
  float v18; // [esp+7Ch] [ebp-5Ch]
  char v19[32]; // [esp+80h] [ebp-58h] BYREF
  char Str[56]; // [esp+A0h] [ebp-38h] BYREF

  system("cls");
  v14 = 1.3;
  v15 = 1.3;
  do
  {
    v13 = -1.2;
    v0 = -1.2;
    do
    {
      v11 = v0 * v0;
      v12 = v15 * v15;
      if ( pow(v12 + v0 * v0 - 1.0, 3.0) - v11 * v15 * v15 * v15 <= 0.0 )
        putchar(42);
      else
        putchar(32);
      v18 = v13 + 0.05;
      v13 = v18;
      v0 = v18;
    }
    while ( v18 <= 1.2 );
    Sleep(0x28u);
    putchar(10);
    v15 = v14 - 0.1;
    v14 = v15;
  }
  while ( v15 >= -1.1 );
  puts("-----Welcome to the landing page-----");
  printf("------Enter your name:");
  scanf("%s", Str);
  printf("------Enter your password:");
  scanf("%s", v19);
  v1 = strlen(Str);
  v2 = 0;
  if ( v1 <= 0 )
  {
LABEL_12:
    v4 = MessageBoxA(0, "Login Successfully!", "UNCTF2021", 0x24u);
    if ( v4 == 1 || v4 == 6 )
    {
      v5 = 0;
      qmemcpy(v17, "pqsd`fl{zmpZsag}wdYVkUNC", 24);  //flag对这串字符串进行变换得到
      v6 = 0;
      do
      {
        v7 = &v17[v5];
        for ( i = 2; i >= 0; --i )
        {
          v9 = *v7;
          v7 += 8;
          Text[v6++] = v9 ^ 0x16;
        }
        ++v5;
      }
      while ( v5 <= 4 );
      Text[v6] = 0;
      MessageBoxA(0, Text, "UNCTF2021", 0x40u);
    }
  }
  else
  {
    v3 = 0;
    while ( v19[v2] == v3 + Str[v2] )  //这里Str中是输入的账号,v19是输入的密码,要满足这样一种关系才能够登录成功
    {
      ++v2;
      v3 += 2;
      if ( v2 >= v1 )
        goto LABEL_12;
    }
    MessageBoxA(0, "Longin Failed!", "UNCTF2021", 0x40u);
  }
  return system("pause");
}

写个简单小脚本或者根据上面的账号和密码关系输入相应账号密码

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

int main()
{
    char s[] = "pqsd`fl{zmpZsag}wdYVkUNC";
    char flag[99];
    int i,j;
    int v5 = 0,v6=0;
    char v9;
    do
    {
        int v7 = v5;
        for(i = 2; i>=0; --i)
        {
            v9 = s[v7];
            v7 += 8;
            flag[v6++] = v9 ^ 0x16;
        }
        ++v5;
    }
    while(v5 <= 4);
    printf("%s",flag);
    return 0;
}

最终flag:flag{refOrL@ve}

rejunk

代码混淆,就只有这两行关键代码

在这里插入图片描述

一个小脚本就行

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

int main()
{

    char s[] = "WQGULxb>2:ooh95=''twk";
    int i,j;
    for(i = 0 ; i < strlen(s) ; i++)
    {
        s[i] ^= i;
        s[i] -= 2;
    }
    printf("%s",s);
    return 0;
}

最终flag: UNCTF{b781cbb29054db}

py_trade

手动逆向,可以参考这个[原创]死磕python字节码-手工还原python源码dis — Python 字节码反汇编器

逆向出来的代码

flag=""
num=[]
k=0
for i in range(len(flag)):
	num[i]=(ord(flag[i]) + i) ^  (k % 3  + 1)
	num[len(flag) -i - 1] = ((( ord(flag[len(flag) - i - 1]) + len(flag) )- i) - 1 ) ^   (k % 3 + 1)
	k+=1
print(num)

#
[115, 120, 96, 84, 116, 103, 105, 56, 102, 59, 127, 105, 115, 128, 95, 124, 139, 49]

然后搞个逆向脚本

out = [115, 120, 96, 84, 116, 103, 105, 56, 102, 59, 127, 105, 115, 128, 95, 124, 139, 49]
flag = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
k = 0
for i in range(18):
    flag[i] = (out[i] ^ (k % 3 + 1)) - i
    flag[17 - i] = (out[17 - i] ^ (k % 3 + 1) ) + i - 17
    k+=1
for j in flag:
    print(chr(j),end='')


py_Trad3_1s_fuNny! ,结果加上flag{}提交就行

ezMaze

一个地图题,要注意点的是,他可以斜着跳,,比如左下,右下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  char *v4; // rdi
  unsigned __int64 v5; // rbx
  const char *v6; // rdx
  int v7; // eax
  int v8; // er9
  int v9; // er8
  int v10; // edx
  char v11; // cl
  int v12; // ecx
  int v13; // ecx
  __int64 v14; // rax

  ((void (__fastcall *)(int, const char **, const char **))sub_1400011A0)(argc, argv, envp);
  dword_140006790[0] = 1;  //这里定义了一张地图,可以用win64debug执行完这一段后在内存中查看
  dword_140006794 = 1;
  dword_1400067B4 = 1;
  dword_1400067CC = 1;
  dword_1400067EC = 1;
  dword_1400067F0 = 1;
  dword_1400067D4 = 1;
  dword_1400067D8 = 1;
  dword_1400067F8 = 1;
  dword_140006810 = 1;
  dword_14000682C = 1;
  dword_140006844 = 1;
  dword_140006840 = 1;
  dword_140006864 = 1;
  dword_140006868 = 1;
  dword_140006884 = 1;
  dword_1400068A0 = 1;
  dword_1400068BC = 1;
  dword_1400068DC = 1;
  dword_14000689C = 1;
  v3 = sub_140001800(std::cout, "Plz inpu7 the P4th :");
  std::ostream::operator<<(v3, sub_1400019D0);
  v4 = byte_140006720;
  v5 = -1i64;
  sub_140001AA0(std::cin, -1i64, byte_140006720);
  do
    ++v5;
  while ( byte_140006720[v5] );
  if ( v5 > 17 )                                // flag长度为17
                                                // 
  {
    v6 = "to0 lon9!t0o long!";
    goto LABEL_26;
  }
  if ( v5 < 17 )
  {
    v6 = (const char *)&unk_140003770;
    goto LABEL_26;
  }
  v7 = dword_140006710;
  v8 = 0;
  v9 = dword_140006714;
  v10 = dword_140006710;
  do
  {
    v11 = *v4;
    if ( *v4 == 'A' )
      goto LABEL_21;
    if ( v11 == 'W' )
    {
      ++v10;
      v12 = v7 % 2;
      ++v7;
      goto LABEL_20;
    }
    if ( v11 == 'E' )
    {
      ++v10;
      v13 = v7 % 2;
      ++v7;
LABEL_16:
      dword_140006710 = v7;
      if ( v13 )
        goto LABEL_23;
      goto LABEL_17;
    }
    if ( v11 != 'D' )
    {
      if ( v11 != 'X' )
      {
        if ( v11 != 'Z' )
        {
          v6 = "What the fuck did you give me?";
          goto LABEL_26;
        }
        --v10;
        v12 = v7 % 2;
        --v7;
LABEL_20:
        dword_140006710 = v7;
        if ( !v12 )
          goto LABEL_23;
LABEL_21:
        --v9;
        goto LABEL_22;
      }
      --v10;
      v13 = v7 % 2;
      --v7;
      goto LABEL_16;
    }
LABEL_17:
    ++v9;
LABEL_22:
    dword_140006714 = v9;
LABEL_23:
    ++v8;
    ++v4;
  }
  while ( v8 < v5 );
  v6 = "Congratulations on this forced to get the right flag, you entered is the correct answer!";
  if ( dword_140006790[7 * v7 + v9] != 1 )  //这里地图7个一行
    v6 = "Try it again little unlucky!";
LABEL_26:
  v14 = sub_140001800(std::cout, v6);
  std::ostream::operator<<(v14, sub_1400019D0);
  return 0;
}

画出来的地图,1是可以走的路径,从左上角开始

1100000
0010000
0101100
0011010
0000100
0000100
0011000
0000110
0000010
0001110
0000010
0000001

看了官方wp才知道这是个六边形的迷宫,我当成普通迷宫写了。。。不过问题不大,写出来就行。。

比如W是往下走,但如果再满足v12 == 1 就除了会往下走一格,还会往左走一格

在这里插入图片描述

在这里插入图片描述

DEWEDXDEWWWEDEWEE

在这里插入图片描述

ezDriver

变种tea加密

在这里插入图片描述

上半部分是加密,下半部分是解密,这里解题代码已经给你了,只要改改就行

在这里插入图片描述

解题脚本

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#define MX \
  ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))
void btea(unsigned int *a1, int a2, unsigned int *a3) {  //解密
    unsigned int v3;
    int v15;
    unsigned int v16;
    unsigned int v17;
    int v18;
    int v19;
    int v20;
    unsigned int v21;
    int v22;
    int v23;
    int v24;
    int v25;

    v3 = a1[0];
    v15 = -a2;   //v15 = 10
    v16 = -1640531527 * (52 / v15 + 6);  //v16 = 0xcc623af3
    //printf("v16 = %x\n",v16);
    v17 = v15;   //v17 = 10 作为从数组最后开始的下标
      do
      {
        v18 = v15 - 1;   //v18 = 9
        v19 = (v16 >> 2) & 3;
        if ( v15 - 1 > 0 )
        {
          v20 = a1[v17 - 1];  //v20 = a1[9]
          printf("v20 = %X , v17 = %X \n",v20,v17);
          v21 = v17 - 1;   //v21 = 9从最后一位开始
          do
          {
            v22 = ((16 * a1[v21 - 1]) ^ (v3 >> 3)) + ((a1[v21 - 1] >> 5) ^ (4 * v3));
            v23 = v19 ^ (v18--) & 3;
            v24 = a3[v23] ^ a1[v21 - 1];
            v23 = v3 ^ v16;
            v25 = v20;
            v20 = a1[v21 - 1];
            v3 = v25 - ((v23 + v24) ^ v22);
            a1[v21--] = v3;
          }
          while ( v18 > 0 );
        }
        *a1 -= ((v3 ^ v16) + (a3[v19 ^ v18 & 3] ^ a1[v17 - 1])) ^ (((16 * a1[v17 - 1]) ^ (v3 >> 3)) + ((a1[v17 - 1] >> 5) ^ (4 * v3)));
        v3 = *a1;
        v16 += 1640531527;
      }
      while ( v16 );
}
//xxtea
int main()
{
  // test
  int i,j;
  /*unsigned int v[] = {0x18,0x4E,0x8E,0x7F,
                        0x2E,0x69,0xB7,0x02,
                        0xEE,0xAA,0x50,0x39,
                        0x90,0xDE,0xE5,0x9F,
                        0xAE,0x4C,0x4D,0x06,
                        0x93,0x71,0x64,0x20,
                        0x8B,0x02,0x34,0xB8,
                        0x3C,0xA1,0x88,0x4A,
                        0x21,0x67,0x1A,0x37,
                        0x83,0xD1,0xF2,0xB1};*/
    unsigned int v[] = {0x7F8E4E18,0x02B7692E,0x3950AAEE,0x9FE5DE90,0x064D4CAE,
                        0x20647193,0xB834028B,0x4A88A13C,0x371A6721,0xB1F2D183};
  //unsigned key[] = {1, 0,0,0,2,0,0,0, 3,0,0,0, 4,0,0,0};
    unsigned key[] = {1,2,3,4};
   for(i = 0 ; i < 10; i++)
  {
      printf("%X  \n",v[i]);
  }
  btea(v, -10, key);

  for(i = 0 ; i < 10; i++)
  {
      printf("%X",v[i]);
  }
  return 0;
}


我这里输出的是16进制,然候要转成字符串形式74636E756F447B66756F795F6E61775F6F745F74635F615F6F5F707565745F667D3F610

在这里插入图片描述

得到tcnuoD{fuoy_naw_ot_tc_a_o_puet_f}?a

然后每四个字符倒一下就行:unctf{Do_you_want_to_a_cup_of_tea?}

chall

秘钥是2021

在这里插入图片描述

codemaker是明文

在这里插入图片描述

然后RC4加密一下就得到flag

在这里插入图片描述

最终flag:UNCTF{Ts/l3pXiG0Fw}

ezPuzzle

这个想了两天没想出来,只是有些思路

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ofo300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值