[zer0pts CTF 2020] easy strcmp

Do you know how relocation works?

tl;dr

angrに投げたら解けた

解説

main関数自体は非常にシンプルです

int64_t main(int argc,char **argv)
{
  int iVar1;

  if (argc < 2) {
    printf("Usage: %s <FLAG>\n",*argv);
  }
  else {
    iVar1 = strcmp(argv[1],"zer0pts{********CENSORED********}");
    if (iVar1 == 0) {
      puts("Correct!");
    }
    else {
      puts("Wrong!");
    }
  }
  return 0;
}

本来はここでCENSOREDの部分を真面目に探しにいくべきなのでしょうが、多分このくらいならangrで解けると見切りを付けてスクリプトを組みました

#!python

import angr
import claripy

### Settings section

# set input type 'arg' or 'stdin'
input_type = 'arg'
# set text showing at getting the flag
suc_txt = 'Correct!'
# flag's length
flag_len = 33
# win address in exec
find_addr = 0x10081e
# lose addresses in exec
avoid_addr = [0x10082c]
# replace to exec's name
p = angr.Project('./chall')

### End of settings section

flag = claripy.BVS('flag', flag_len * 8)
argv = [p.filename]
argv.append(flag)

if input_type == 'arg':
    state = p.factory.entry_state(args=argv)
else:
    state = p.factory.entry_state(stdin=flag)

# bind charcters only printables
for b in flag.chop(8):
    state.add_constraints(b >= 0x21)
    state.add_constraints(b < 0x7f)

simgr = p.factory.simulation_manager(state)

# explore
simgr.explore(find=(find_addr), avoid=(avoid_addr))
# simgr.explore(find=lambda s: suc_txt.encode() in s.posix.dumps(1))

# check
if len(simgr.found) >= 1:
    if input_type == 'arg':
        print(simgr.found[0].solver.eval(argv[1], cast_to=bytes))
    else:
        print(simgr.found[0].posix.dumps(0))
else:
    for i in simgr.deadended:
        if i.posix.dumps(1).find(suc_txt.encode()) != -1:
            if input_type == 'arg':
                print(i.solver.eval(argv[1], cast_to=bytes))
            else:
                print(i.posix.dumps(0))
            exit()
    print("Not found")
metarin@archdesk ..ed/Project/CTF/zer0pts/rev/easy_strcmp % ./angr_es.py 
/home/metarin/pyenv/angr/lib/python3.8/site-packages/pysmt/walkers/generic.py:43: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working
  if len(nodetypes) == 1 and isinstance(nodetypes[0], collections.Iterable):
WARNING | 2020-03-09 11:05:25,583 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
WARNING | 2020-03-09 11:05:27,044 | angr.state_plugins.symbolic_memory | The program is accessing memory or registers with an unspecified value. This could indicate unwanted behavior.
WARNING | 2020-03-09 11:05:27,044 | angr.state_plugins.symbolic_memory | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2020-03-09 11:05:27,044 | angr.state_plugins.symbolic_memory | 1) setting a value to the initial state
WARNING | 2020-03-09 11:05:27,044 | angr.state_plugins.symbolic_memory | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2020-03-09 11:05:27,044 | angr.state_plugins.symbolic_memory | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY_REGISTERS}, to suppress these messages.
WARNING | 2020-03-09 11:05:27,044 | angr.state_plugins.symbolic_memory | Filling memory at 0x7fffffffffefff8 with 176 unconstrained bytes referenced from 0x108e990 (strcmp+0x0 in libc.so.6 (0x8e990))
b'zer0pts{l3ts_m4k3_4_DETOUR_t0d4y}'
metarin@archdesk ..ed/Project/CTF/zer0pts/rev/easy_strcmp % 

zer0pts{l3ts_m4k3_4_DETOUR_t0d4y}
たぶん想定解法ではありません