ångstromCTF Reversing High Quality Checks

High Quality Checks

After two break-ins to his shell server, kmh got super paranoid about a third! He's so paranoid that he abandoned the traditional password storage method and came up with this monstrosity! I reckon he used the flag as the password, can you find it?

実行ファイルが与えられる。

~/Desktop/ångstromCTF/Reversing/High Quality Checks ᐅ file high_quality_checks 
high_quality_checks: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=e7556b55e0c73b4de8b3f387571dd59c3535a0ee, not stripped

~/Desktop/ångstromCTF/Reversing/High Quality Checks ᐅ chmod +x high_quality_checks

~/Desktop/ångstromCTF/Reversing/High Quality Checks ᐅ ./high_quality_checks 
Enter your input:
a
Flag is too short.

ELF 64-bitで実行すると入力値を比較しているように見える。 IDAで解析していく。

main関数では入力を受け取りcheck関数で比較して正しければYou found the flag! 間違ってたらThat's not the flag.入力値が短いときにはFlag is too short.を出力する。

f:id:Yunolay:20190420203843p:plain

check関数はというと

_BOOL8 __fastcall check(char *a1)
{
  return (unsigned int)d((_DWORD *)a1 + 3)
      && (unsigned int)v((unsigned int)*a1)
      && (unsigned int)u((unsigned int)a1[16], (unsigned int)a1[17])
      && !(unsigned int)k((unsigned int)a1[5])
      && !(unsigned int)k((unsigned int)a1[9])
      && (unsigned int)w(a1 + 1)
      && (unsigned int)b((__int64)a1, 0x12u)
      && (unsigned int)b((__int64)a1, 4u)
      && (unsigned int)z(a1, 108LL)
      && (unsigned int)s((__int64)a1);
}

_BOOL8 __fastcall d(_DWORD *a1)
{
  return *a1 == 0x30313763;
}

_BOOL8 __fastcall v(char a1)
{
  return (char)(a1 ^ 0x37) == (unsigned int)n(172LL);
}
(snip)

関数を読んでいるが計算していくのはめんどくさい。

You found the flag!を出力させればいいだけなのでangrを使う。

github.com

こうしたい。

f:id:Yunolay:20190420204432p:plain

That's not the flag.とFlag is too short.を避けてYou found the flag!にたどり着く入力値を探したい。

solve.py

import angr

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

a = p.surveyors.Explorer(find = 0x0000000000400ACB, avoid = (0x0000000000400AD9, 0x0000000000400AA8)).run()

if len(a.found) > 0:
    print 'Dump stdin at succeeded():'
    s = a.found[0].state
    print "%r" % s.posix.dumps(0)
(ENV) ~/angr/High Quality Checks ᐅ python solve.py
WARNING | 2019-04-20 04:26:33,256 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
Dump stdin at succeeded():
'actf{fun_func710n5}'

FLAG : actf{fun_func710n5}

参考にしました。

saotake.hatenablog.com

inaz2.hatenablog.com