상세 컨텐츠

본문 제목

[angr_ctf] 00_angr_find

SYSTEM HACKING/CTF, etc

by koharin 2022. 5. 14. 15:44

본문

728x90
반응형

파일 정보

$ file 00_angr_find 
00_angr_find: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=33a8c07c85370a2b45a17cc78b035b56d2dd7f8e, not stripped

 

파일 실행

파일을 실행하면 비밀번호를 입력 받고 틀리면 “Try again.”을 출력해준다.

옮을 경우 출력해주는 루틴도 있을 것이다.

더 정확하게 분석하기 위해 코드분석을 해보자.

 

코드 분석

main() 함수

int __cdecl main(int argc, const char **argv, const char **envp)
{
  signed int i; // [esp+1Ch] [ebp-1Ch]
  char s1[9]; // [esp+23h] [ebp-15h]
  unsigned int v6; // [esp+2Ch] [ebp-Ch]

  v6 = __readgsdword(0x14u);
  printf("Enter the password: ");
  __isoc99_scanf("%8s", s1);
  for ( i = 0; i <= 7; ++i )
    s1[i] = complex_function(s1[i], i);
  if ( !strcmp(s1, "ILIUFVJF") )
    puts("Good Job.");
  else
    puts("Try again.");
  return 0;
}
  • s1에 8개 문자를 입력 받고, complex_function에서 입력 문자열 내 문자마다 연산을 진행한다.
  • 이후 “ILIUFVJF”와 연산 후의 s1가 동일하면 “Good Job.”을, 동일하지 않으면 “Try again.”을 출력해준다.

 

complex_function()

int __cdecl complex_function(signed int a1, int a2)
{
  if ( a1 <= '@' || a1 > 'Z' )
  {
    puts("Try again.");
    exit(1);
  }
  return (3 * a2 + a1 - 'A') % 26 + 'A';
}
  • 문자가 주어진 조건을 만족하지 않으면 종료하고, 그렇지 않으면 연산 결과를 리턴한다.

angr를 사용하므로 복잡한 함수에서 계산을 구해서 입력값을 구하지 않고, “Good Job.” 경로로 가는 주소를 찾으면 된다.

.text:0804865C loc_804865C:                            ; CODE XREF: main+4F↑j
.text:0804865C                 cmp     [ebp+var_1C], 7
.text:08048660                 jle     short loc_804862F
.text:08048662                 sub     esp, 8
.text:08048665                 push    offset s2       ; "ILIUFVJF"
.text:0804866A                 lea     eax, [ebp+s1]
.text:0804866D                 push    eax             ; s1
.text:0804866E                 call    _strcmp
.text:08048673                 add     esp, 10h
.text:08048676                 test    eax, eax
.text:08048678                 jz      short loc_804868C
.text:0804867A                 sub     esp, 0Ch
.text:0804867D                 push    offset s        ; "Try again."
.text:08048682                 call    _puts
.text:08048687                 add     esp, 10h
.text:0804868A                 jmp     short loc_804869C
.text:0804868C ; ---------------------------------------------------------------------------
.text:0804868C
.text:0804868C loc_804868C:                            ; CODE XREF: main+9A↑j
.text:0804868C                 sub     esp, 0Ch
.text:0804868F                 push    offset aGoodJob ; "Good Job."
.text:08048694                 call    _puts
.text:08048699                 add     esp, 10h
.text:0804869C

main() 함수에서 좀더 low-level로 처리 과정을 살펴보면, _strcmp 함수 호출 결과 리턴값이 eax 레지스터에 저장되는데, test eax, eax는 eax AND eax 결과가 0인지 음수인지 확인하는 것으로 0이면 jz, 즉 zero이면 loc_804868C로 jump한다.

0x804868C 주소에서 코드를 확인해보면 “Good Job.”을 출력해주는 루틴이다.

따라서 0x804868C가 angr를 이용해서 찾아야 하는 주소이다.

 

Exploit

#!/usr/bin/python 
import angr

# address to find
FIND = 0x804868C

# create angr project
project = angr.Project('./00_angr_find', auto_load_libs=False)

# tell angr where to start executing (main() or somewhere)
# add options to indicate angr to start from main()
state = project.factory.entry_state(add_options={angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY, angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS})

# create a simulation manager and initialize it with starting state

#simgr = project.factory.simulation_manager(state)
simgr = project.factory.simgr(state)

# explore possible path while executing binary
simgr.explore(find=FIND)

if simgr.found:
    # if address found, state saved in found stash. if failed it is empty
    print(simgr.found[0])

    # print the string that angr wrote to stdin to find solution
    print(simgr.found[0].posix.dumps(0))
else:
    raise Exception('Could not find the solution')

위와 같이 코드를 작성하고 실행해보자.

“Good Job.”을 출력해주는 루틴으로 갈 수 있는 입력값은 “IICLTGRK”다.

 

다시 실행 파일을 실행해서 해당 문자열을 입력으로 주면 “Good Job.”이 출력된다.

 

728x90
반응형

'SYSTEM HACKING > CTF, etc' 카테고리의 다른 글

[angr_ctf] 02_angr_find_condition  (0) 2022.05.14
[angr_ctf] 01_angr_avoid  (0) 2022.05.14
GoogleCTF 2016 unbreakable_0  (0) 2022.05.11
[DefCamp CTF 2015 Quals] Entry Language (Reverse 100)  (0) 2022.05.11
[angr] fauxware  (0) 2022.05.09

관련글 더보기