프로토스타

[프로토스타] stack3

-dP- 2019. 1. 9. 15:14

stack3.c


#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> void win() { printf("code flow successfully changed\n"); } int main(int argc, char **argv) { volatile int (*fp)(); char buffer[64]; fp = 0; gets(buffer); if(fp) { printf("calling function pointer, jumping to 0x%08x\n", fp); fp(); } }



출처: http://liveoverflow.com/binary_hacking/protostar/stack3.html



1. 해결 및 분석



1-1. pwn tool 다운로드


https://www.youtube.com/watch?v=anKJKi7e4HM


이거 보시고 따라하시면 됩니다.


1-2. stack3.c 저장




1-3.  컴파일





gcc -z execstack -w -no-pie -o stack3 stack3.c


컴파일이 정상적으로 됐음을 알 수 있다.



1-4 실행



스택 구조


buffer

fp


코드상에서 fp를 수정하는 부분이 없다.


그렇다면 앞서 해왔던 문제풀이처럼 buffer을 넘치게 채우면 fp를 수정할 수 있다.


즉 fp까지 데이터를 넘치게 하여 fp를 수정하라는 뜻


하지만 fp는 win 함수의 주소값을 가져야 한다.



1-5. 위치 확인



buffer와 fp 사이에 거리를 확인해보자.


gdb ./stack3


disas main


b* main+40 (cmp 비교하는 곳에) / b *main+ 80해도 상관 없음.





rbp의 주소는 Peda를 통해 확인해 보자.




위 드래그 돼 있는 RBP의 주소값을 통해서 gdb를 살펴보면 main + 27이다.


main+27 : mov rdi, rax이므로 rax를 가져오는 값인 0x50과 브레이크포인트가 걸린 fp의 0x8을 연산하면 된다.


print 0x50 - 0x8


0x50 - 0x8 = 72_10(_10은 10진수로라는 의미)


또는



x/10 $rbp-0x8을 통해 cmp 주소 확인


드래그된 부분이 cmp 부분이므로


즉, buffer 72개 채우면 fp에 도달할 수 있다라는 의미.



1-6. fp를 win으로 덮어 쓰기





gdb ./stack3


disas win


드래그된 첫 번째 주소를 가져온다.


커맨드상에서 아스키코드를 입력하는데 한계가 있기 때문에 파이썬으로 작성한다.



1-7. 코드 작성




위에서 pwn을 보고 왔다면 이해가 될 것이다.


payload는 우리가 공격하는 코드로써 buffer를 72개 채운 후 fp에 win() 함수 주소를 전달하여 win() 함수가 실행되게 한다.





짜란 성공!


return to lib 라고 합니다.~


참고 자료: https://www.inflearn.com/course/%ED%94%84%EB%A1%9C%ED%86%A0%EC%8A%A4%ED%83%80/


참고 서적: [해킹, 공격의 예술] http://acornpub.co.kr/book/hacking-art2


피드백 환영입니다!

'프로토스타' 카테고리의 다른 글

[프로토스타] stack5-1 (스택 접근)  (0) 2019.01.10
[프로토스타] stack4  (0) 2019.01.09
[프로토스타] stack2  (0) 2019.01.09
[프로토스타] stack1  (0) 2019.01.08
[프로토스타] stack0  (0) 2019.01.04