天天看点

reverse-BUUCTF

1、easyre

ida中搜索字符串即可得到flag:

reverse-BUUCTF

2、helloword

拿到是apk文件,jeb中打开,即可得到flag

reverse-BUUCTF

3、reverse1

elf文件,IDA中打开,搜索字符串

reverse-BUUCTF

定位到判断函数:

reverse-BUUCTF

查看伪代码:

__int64 sub_1400118C0()
{
  char *v0; // rdi
  signed __int64 i; // rcx
  size_t v2; // rax
  size_t v3; // rax
  char v5; // [rsp+0h] [rbp-20h]
  int j; // [rsp+24h] [rbp+4h]
  char Str1; // [rsp+48h] [rbp+28h]
  unsigned __int64 v8; // [rsp+128h] [rbp+108h]

  v0 = &v5;
  for ( i = 82i64; i; --i )
  {
    *(_DWORD *)v0 = -858993460;
    v0 += 4;
  }
  for ( j = 0; ; ++j )
  {
    v8 = j;
    v2 = j_strlen(Str2);
    if ( v8 > v2 )
      break;
    if ( Str2[j] == 111 )
      Str2[j] = 48;
  }
  sub_1400111D1("input the flag:");
  sub_14001128F("%20s", &Str1);
  v3 = j_strlen(Str2);
  if ( !strncmp(&Str1, Str2, v3) )
    sub_1400111D1("this is the right flag!\n");
  else
    sub_1400111D1("wrong flag\n");
  sub_14001113B(&v5, &unk_140019D00);
  return 0i64;
}
           

很容易发现flag即为Str2的值,即:

reverse-BUUCTF

4、reverse2

同样是elf文件,IDA中打开,定位主函数,查看伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  int stat_loc; // [rsp+4h] [rbp-3Ch]
  int i; // [rsp+8h] [rbp-38h]
  __pid_t pid; // [rsp+Ch] [rbp-34h]
  char s2; // [rsp+10h] [rbp-30h]
  unsigned __int64 v8; // [rsp+28h] [rbp-18h]

  v8 = __readfsqword(0x28u);
  pid = fork();
  if ( pid )
  {
    argv = (const char **)&stat_loc;
    waitpid(pid, &stat_loc, 0);
  }
  else
  {
    for ( i = 0; i <= strlen(&flag); ++i )
    {
      if ( *(&flag + i) == 105 || *(&flag + i) == 114 )
        *(&flag + i) = 49;
    }
  }
  printf("input the flag:", argv);
  __isoc99_scanf("%20s", &s2);
  if ( !strcmp(&flag, &s2) )
    result = puts("this is the right flag!");
  else
    result = puts("wrong flag!");
  return result;
}
           

变量flag的值即为flag:

reverse-BUUCTF

5、新年快乐

拿到的是PE文件,查壳后发现UPX壳:

reverse-BUUCTF

脱壳后IDA中打开,搜索字符串定位函数:

reverse-BUUCTF
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  char v4; // [esp+12h] [ebp-3Ah]
  __int16 v5; // [esp+20h] [ebp-2Ch]
  __int16 v6; // [esp+22h] [ebp-2Ah]

  sub_401910();
  strcpy(&v4, "HappyNewYear!");
  v5 = 0;
  memset(&v6, 0, 0x1Eu);
  printf("please input the true flag:");
  scanf("%s", &v5);
  if ( !strncmp((const char *)&v5, &v4, strlen(&v4)) )
    result = puts("this is true flag!");
  else
    result = puts("wrong!");
  return result;
}
           

由伪代码可知,flag即为v4的值即HappyNewYear!

6、xor

同样是elf文件,IDA中打开,定位main函数查看伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v3; // rsi
  int result; // eax
  signed int i; // [rsp+2Ch] [rbp-124h]
  char v6[264]; // [rsp+40h] [rbp-110h]
  __int64 v7; // [rsp+148h] [rbp-8h]

  memset(v6, 0, 0x100uLL);
  v3 = (char *)256;
  printf("Input your flag:\n", 0LL);
  get_line(v6, 256LL);
  if ( strlen(v6) != 33 )
    goto LABEL_12;
  for ( i = 1; i < 33; ++i )
    v6[i] ^= v6[i - 1];
  v3 = global;
  if ( !strncmp(v6, global, 0x21uLL) )
    printf("Success", v3);
  else
LABEL_12:
    printf("Failed", v3);
  result = __stack_chk_guard;
  if ( __stack_chk_guard == v7 )
    result = 0;
  return result;
}
           

大致逻辑为:用户输入一个长度为33的字符串,字符串中的字符分别和前一个字符异或(对应得ASCII码)后和变量global的前0x21个字符比对。逻辑并不复杂,提取global的值:

reverse-BUUCTF
reverse-BUUCTF

提取后编写脚本得到flag:

List=[
  0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11, 
  0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F, 
  0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F, 
  0x47, 0x32, 0x4F]
flag=chr(List[0])
i=1
while True:
    if i<len(List):
        flag+=chr(List[i]^List[i-1])
        i+=1
    else:
        break
print(flag)
           

7、内涵的软件

PE文件,直接在IDA中打开,定位到主函数,falg明文储存:

reverse-BUUCTF

这里需要注意的是flag是: flag{DBAPP{49d3c93df25caad81232130f3d2ebfad}}

8、reverse3

PE文件,直接在IDA中打开,搜索字符串,定位函数:

reverse-BUUCTF
reverse-BUUCTF

查看伪代码:

__int64 main_0()
{
  size_t v0; // eax
  const char *v1; // eax
  size_t v2; // eax
  int v3; // edx
  __int64 v4; // ST08_8
  signed int j; // [esp+DCh] [ebp-ACh]
  signed int i; // [esp+E8h] [ebp-A0h]
  signed int v8; // [esp+E8h] [ebp-A0h]
  char Dest[108]; // [esp+F4h] [ebp-94h]
  char Str; // [esp+160h] [ebp-28h]
  char v11; // [esp+17Ch] [ebp-Ch]

  for ( i = 0; i < 100; ++i )
  {
    if ( (unsigned int)i >= 0x64 )
      j____report_rangecheckfailure();
    Dest[i] = 0;
  }
  sub_41132F("please enter the flag:");
  sub_411375("%20s", &Str);
  v0 = j_strlen(&Str);
  v1 = (const char *)sub_4110BE(&Str, v0, &v11);
  strncpy(Dest, v1, 0x28u);
  v8 = j_strlen(Dest);
  for ( j = 0; j < v8; ++j )
    Dest[j] += j;
  v2 = j_strlen(Dest);
  if ( !strncmp(Dest, Str2, v2) )
    sub_41132F("rigth flag!\n");
  else
    sub_41132F("wrong flag!\n");
  HIDWORD(v4) = v3;
  LODWORD(v4) = 0;
  return v4;
}
           

sub_4110BE函数处理输入的字符串之后再对处理后得到的字符串做移位操作然后再和变量Str2比对,整个逻辑并不复杂,跟踪到函数sub_4110BE可以发现函数sub_4110BE应该是将字符串进行base64编码,编写脚本如下:

import base64
s='[email protected]@dH'
s1=''
i=0
while i<len(s):
    s1+=chr(ord(s[i])-i)
    i+=1
flag=base64.b64decode(s1)
print(flag)