int main(int argc, char **argv) { char buffer[64]; gets(buffer);
}
1. 해결
1-1. stack5.c 저장 및 aslr 제거
aslr 제거
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
가변적 스택을 고정하기 위함.
고정하지 않으면 shell code의 위치가 변하므로 고정해주어야 한다.
출처: https://askubuntu.com/questions/318315/how-can-i-temporarily-disable-aslr-address-space-layout-randomization
1-2. msfvenom 사용
msfvenom -l | grep linux ;리눅스를 통해 만들 수 있는 쉘코드를 알려준다.
msfvenom -p linux/x64/exec CMD='/bin/sh' -f python
;쉘코드 가져온다.
gcc -z exestack -w -no-pie -o stack5 stack5.c
컴파일 해준다.
1-3. 코드 작성
;
위와 같이 작성하면 된다. 단, ret_addr는 stack에 따라 달라지므로 가변적이다.
분석은 아래에서 자세히 하겠다.
1-4. 실행
성공 따란!
2. 분석
2-1. buffer 채우기
스택의 구조를 생각해보자.
buffer
ebp
ret
shell code
ebp가 원래 main 위치에 있다고 하면
buffer
ret
shell code
buffer와 ret 값을 꽉 채우면 그 다음 주솟값은 shell code의 주솟값이다.
즉 buffer와 ret의 위치와 주솟값을 알면 된다.
여태까지 해왔던 것처럼
gdb ./stack5
disas main
브레이크 포인트는 리턴되기 전 레지스터 값을 알아야 하므로
b *main+38
pattern create 100 해서 생성된 문자로
r
(생성된 문자)
그 후에 stack에 맨 위에 있는 문자를 복사하여
pattern offset (복사한 문자)
offset이 72개임을 알 수 있다.
즉 buffer는 72개를 채우면 다 채울 수 있다.
2-2. RETURN_ADDRESS 구하기
우선 ret_addr 주소를 0xFFFFFFFFFFFFFFFF 16개로 아래와 같이 해준다.
그런 후 터미널을 하나 더 연다.
terminal->new window
왼쪽 터미널에
python stack5.py 먼저 입력 후
pid를 복사하여
오른쪽 터미널에 gdb ./stack5 pid 입력하면 위와 같이 된다.
오른쪽 터미널에 disas main
b *main+38
conti (run이 아니라 conti를 해줘야 한다.)
왼쪽 터미널에서 엔터(아무 값이나 상관 없음)를 누르면
오른쪽 터미널에 이렇게 뜬다.
우리는 ret_addr = 0xFFFFFFFFFFFFFFFF 넣었다.
ret_addr에 0xFFFFFFFFFFFFFFFF가 잘 들어감을 볼 수 있다.
ret_addr 다음 주솟값이 쉘 코드이므로 ret_addr에 드래그된 부분을 넣으면 된다.
위와 같이 수정하면 쉘이 잘 진행됨을 알 수 있다.
성공!
참고 자료: https://www.inflearn.com/course/%ED%94%84%EB%A1%9C%ED%86%A0%EC%8A%A4%ED%83%80/
피드백 환영입니다!
'프로토스타' 카테고리의 다른 글
[프로토스타] stack6 (함정을 지나 ret하기) (0) | 2019.01.15 |
---|---|
[프로토스타] stack5-2 (return to library) (0) | 2019.01.15 |
[프로토스타] stack4 (0) | 2019.01.09 |
[프로토스타] stack3 (0) | 2019.01.09 |
[프로토스타] stack2 (0) | 2019.01.09 |