반응형
문제분석 & 풀이
코드 분석
1. shell() : level17의 권한으로 셸 실행
2. printit() : 출력문 출력
3. crap, *call, buf[]를 선언했으며 call에는 printit()의 주소를 넣어주고있다.
4. fgets()을 통해 48바이트만큼 사용자에게 입력값을 받는다.
5. call()을 호출하여 printit()를 실행한다.
call에 printit()의 주소를 저장하고 call()을 호출하여 printit()을 실행하고 있다.
그렇다면 call에 저장된 함수의 주소를 printit() → shell()로 바꿔줄 수 있다면, printit()이 아닌 shell()을 실행하여 level17의 셸을 얻어낼 수 있다.
어떻게 call에 저장된 주소값을 바꿀 수 있을까?
call의 위치가 buf 상단이고 우리는 buf에 입력값을 저장한다. 따라서 BOF로 call 영역에 침범하여 printit() 주소를 shell() 주소로 바꾸면 된다.
○ 공격시나리오
1. shell() 주소를 구한다.
2. call 위치를 알아내고 BOF를 통해 1번에서 구한 shell을 덮어쓸 페이로드를 작성한다.
3. 페이로드를 실행하여 level17의 권한을 탈취한다.
shell() 주소와 call의 위치등을 알아내기 위해서는 GDB로 attackme를 디버깅해야한다.
GDB로 main을 분석했다.
0x38(56)바이트 만큼의 공간을 할당하고 있다.
이후 [ebp-16]에 0x8048500을 넣어주고있는데, 0x8048500이 printit()의 주소이며 [ebp-16]이 *call의 위치임을 알 수 있다.
다음으로 shell() 주소를 구하기 위해 shell() 코드를 확인했다.
0x080484d0가 shell() 주소임을 알 수 있다.
shell의 주소와 *call의 위치를 알아냈으니 페이로드를 작성해보자.
스택 구조는 위와 같으며 페이로드를 작성하면 다음과 같다.
"A"*40+["shell() 주소"]
"A"*40+"\xd0\x84\x04\x08"
(python -c 'print "A"*40+"\xd0\x84\x04\x08"';cat) | ./attackme
페이로드를 실행해보자.
결과는?
반응형