-
[Stack 6]System/Protostar 2018. 2. 10. 00:29
[Stack6 Code]
[Stack6 실행]
우선 프로그램을 실행하면 입력한 값을 그대로 출력해준다.
gets( )에서 BOF취약점이 있으며, 이 점을 이용해서 RET를 변조할 수 있다.
gets( ) 다음에 __builtin_return_address(0)함수로 리턴주소를 ret에 저장한다
그 다음에 ret이 0xbf로 시작하면, 즉 스택와 동일한 주소면 종료하는 조건문이 있다.
따라서 쉘코드로는 쉘을 따내지 못한다.
그래서 RTL을 이용해서 쉘을 따냈다.
[RTL]
ReturnToLiblary
RET공간에 시스템 라이브러리 함수의 주소값을 넣어서
함수가 끝나고 RET주소로 복귀할 때, 시스템 함수가 실행되도록 하는 것이다.
자세한 설명 : [RTL이란?]
우선 RTL공격을 하려면 System라이브러리 주소와 /bin/sh문자열을 인자값으로 넘길 방법을 알아내야한다.
( system("/bin/sh <-이부분") )
난 라이브러리안에 /bin/sh부분의 offset을 구한 후, libc base주소에 더해서 /bin/sh를 인자값으로 넘겼다.
실습을 통해서 알아보도록 하자
[Stack6 getpath( )]
gets( ) 실행 직후에 BP를 걸고 실행했다.
그 후 A를 버퍼값 64만큼 입력해주고 스택상황을 확인해봤다.
그 후 RET주소가 저장돼있는 EIP를 찾기위해서 ESP와 EIP의 offset을 구했다.
여기서 EIP의 offset은 80인 것을 확인할 수 있다.
그럼 버퍼에 A를 80만큼 입력하고 조건문에 걸리도록 RET에 0xbf000000을 넣어봤다.
[RET 0xBF00 0000]
RET주소가 0xBF00 0000으로 변조되니 코드상에 예외처리에 걸려버렸다.
(주소가 BF로만 시작해도 조건문에 걸리게된다.)
이제 RTL공격에 사용될 시스템 함수의 주소값을 구해보도록 하자
[system address]
system 라이브러리 함수 주소는 [0xb7ecffb0] 인 것을 확인 할 수 있다.
시스템 함수 주소도 구했으니 이제 /bin/sh문자열 주소만 찾으면 된다.
여러가지 방법이 있겠지만 나는 libc안에 문자열을 가져와서 넘겨줬다.
여기서 사용되는 libc버전을 먼저 알아야한다.
[libc 버전]
ldd로 확인이 가능하다.
여기서 /lib안에 있는 libc.so.6을 사용한다.
[/bin/sh offset]
objdump로 /lib/libc.so.6 안에서 grep으로 sh.exit문자열을 찾으면
사진처럼 연속된 /bin/sh 문자열의 offset[0x11f3bf]을 구할 수 있다.
이 offset을 libc base주소에 더해주면 저 문자열의 주소를 얻을 수 있다.
libc base주소를 알아내려면 우리가 찾은 [system함수] - [system함수의 offset] 해주면 된다.
[system offset]
이번에도 objdump로 확인해보면 system함수의 offset은 [0x38fb0] 인 것을 알 수 있다.
[0xb7ecffb0] - [0x38fb0] = [0xB7E97000]
libc base 주소는 [0xB7E97000]이다.
여기에 /bin/sh의 offset을 더하면?
[0xB7E97000] + [0x11f3bf] = [0xB7FB63BF]
따라서 /bin/sh문자열의 위치는 [0xB7FB63BF]이다.
자 필요한 정보들은 다 얻었으니 이제 쉘을 따보도록 하자
[Stack6 exploit]
중간에 AAAA 값은 System함수의 RET값이다.
위에 정리글을 보면 자세히 설명되어 있다.
이상으로 Stack6 write up을 마치도록 한다.
댓글