UUTCTF Reversing Correct Pass

Correct Pass

Description

Find the correct password in order to access the flag.

ELF 32-bitが与えられる。

$ file pass
pass: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=4f22a0a1bfc2ea255594a1b7373578176eb37c77, stripped

標準入力から比較してるっぽい。

~/ctf/Correct Pass ᐅ ./pass
[*] Enter the flag:aaa
[*] Wrong !!

IDA Proで解析する。

f:id:Yunolay:20190426115537p:plain

入力値が違った場合は以下が出力される。

[*] Wrong !!
[*] Try again!

入力値の比較はmainからなんかいろいろ呼んでるっぽい。

{
  int v0; // ebx
  char v1; // bl
  int v2; // ebx
  signed int v4; // [esp+0h] [ebp-10h]
  char *s; // [esp+4h] [ebp-Ch]

  v4 = 1;
  printf("[*] Enter the flag:");
  if ( !ptrace(0, 0, 1, 0) )
    v4 = 8;
  if ( ptrace(0, 0, 1, 0) == -1 )
    v4 *= 2;
  s = (char *)malloc(v4 + 1);
  memset(s, 0, v4 + 1);
  fgets(s, v4 + 1, stdin);
  if ( sub_804858B(v4, 16) == v4 && sub_80485EA(s) == v4 )
  {
    v0 = s[v4 / 2 - 1];
    if ( v0 == sub_80485A2(v4) && s[sub_804858B(3, 3) - 1] == 101 )
    {
      v1 = s[6];
      if ( v1 == s[sub_804858B(2, 2)] )
      {
        v2 = *s;
        if ( v2 == sub_8048623(s[6]) - 1 )
        {
          if ( !sub_8048668(s) )
          {
            if ( sub_80486DF(s) )
            {
              if ( sub_8048717(s) )
              {
                if ( !sub_804874F(s) )
                {
                  if ( sub_8048787(s) )
                  {
                    printf("[*] Flag: UUTCTF{MD5(%s)}\r\n", s);
                    free(s);
                    exit(0);
                  }
                  puts("[*] Try again!\r");
                  free(s);
                  exit(1);
                }
                puts("[*] Try again!\r");
                free(s);
                exit(1);
              }
              puts("[*] Try again!\r");
              free(s);
              exit(1);
            }
            puts("[*] Try again!\r");
            free(s);
            exit(1);
          }
          puts("[*] Try again!\r");
          free(s);
          exit(1);
        }
      }
    }
  }
  puts("[*] Wrong !!");
  free(s);
  return 0;
}

とりあえずangrに[] Wrong !!と[] Try again!を回避してprintf("[*] Flag: UUTCTF{MD5(%s)}\r\n", s);にたどり着くようにやっていただく。

import angr

binary = './pass'
p = angr.Project(binary)

a = p.surveyors.Explorer(find = 0x08048A99, avoid = (0x08048AC4, 0x0804896F, 0x080489AB, 0x080489E7, 0x08048A23, 0x08048A5F)).run()

if len(a.found) > 0:
    print 'Dump stdin at succeeded():'
    s = a.found[0].state
    print "%r" % s.posix.dumps(0)
ENV) ~/ctf/Correct Pass ᐅ python solve.py 
WARNING | 2019-04-25 19:50:15,980 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
Dump stdin at succeeded():
'Awesome_M0v!!;-)'

入力がAwesome_M0v!!;-)だとわかったのでMD5する。

Awesome_M0v!!;-)
7e7d9d8d6a7ad4a2b3d0f0b4abc1d9bf

FLAG : UUTCTF{7e7d9d8d6a7ad4a2b3d0f0b4abc1d9bf}