Lazenca | Return to Shellcode

133210·2021년 7월 23일
0

2020 시스템

목록 보기
11/25
post-thumbnail

1.1 Return to Shellcode

Return address 영역에 Shellcode가 저장된 주소로 변경해, Shellcode를 호출하는 방식

1.2 CALL & RET instruction

1) CALL 명령어: Return address(CALL 명령어 다음 명령어의 위치(주소값))를 Stack에 저장하고, 피연산자 주소로 이동함
2) RET 명령어: POP 명령어를 이용해 RSP 레지스터가 가리키는 Stack 영역에 저장된 값을 RIP(EIP)에 저장 후, 해당 주소로 이동함
3) Stack 영역에 저장된 Return address 값을 변경할 수 있다면 프로그램의 흐름 변경 가능

1.3 Proof of concept

1) test.c: main() 함수에서 vuln() 함수 호출, vuln() 함수는 아무런 동작을 하지 않음

2) Call / RET

main+9: vuln 함수를 호출하는 CALL 명령어 (다음 명령어의 위치: 0x4004eb)
vuln+0: vuln 함수의 첫번째 명령어

vuln() 함수의 호출 전 RSP(ESP) 레지스터가 가리키는 Stack의 위치는 0x7fffffffdeb0이며, 해당 영역에 저장되어 있는 값은 0x4004f0

vuln() 함수의 호출 후 RSP(ESP) 레지스터가 가리키는 Stack의 위치는 0x7fffffffdea8이며, 해당 영역에 저장되어 있는 값은 0x4004eb (Call 명령어 다음 명령어의 위치)
CALL 명령어에 의해 Stack에 호출된 함수가 종료된 후에 이동할 주소 값을 저장함

RET 명령어 실행 전 RSP(ESP) 레지스터가 가리키는 Stack의 위치는 0x7fffffffe4a8이며, 해당 영역에 저장되어 있는 값은 0x4004eb

RET 명령어 실행 후 RSP(ESP) 레지스터가 가리키는 Stack의 위치는 0x7fffffffdeb0이며, 해당 영역에 저장되어 있는 값은 0x4004f0
RET 명령어에 의해 CALL 명령어 다음 명령어가 있는 곳(0x4004eb)로 이동하는 것을 볼 수 있음
RET 명령어에 의해 Stack에 저장된 주소 값을 RIP 레지스터에 저장하여 해당 주소로 이동하게 됨
Stack에 저장된 Return address를 변경할 수 있다면 공격자는 원하는 영역으로 이동 가능

stack Overwrite에 의해 변경된 Return address 영역으로 이동
Return address 영역(0x7fffffffdea8)에 저장되어 있던 값은 main+14, SET 명령어로 변경

RET 명령어는 RSP 레지스터가 가리키는 주소 값이 0x4004d6이기 때문에 0x4004d6 영역으로 이동

Return address 영역에 Shellcode가 저장된 주소로 저장하면, 해당 영역으로 이동하게 됨

1.4 Permission in memory

메모리 권한에 대한 이해 필요

1) read(r): 메모리 영역의 값을 읽을 수 있음
2) write(w): 메모리 영역에 값을 저장할 수 있음
3) excute(x): 메모리 영역에서 코드 실행 가능
4) GCC는 기본적으로 DEP가 적용되기 때문에 코드가 저장된 영역에만 실행권한이 설정되며, 데이터가 저장되는 영역에는 실행권한이 설정되지 않음
5) Shellcode를 실행하기 위해 Shellcode가 저장된 영역은 excute 권한이 설정되어 있어야 함
6) DEP를 해제하기 위해 GCC 옵션으로 “-z execstack”을 추가해야 함. 해당 옵션으로 인해 데이터 저장 영역에도 excute 권한이 설정됨. 즉, Stack에 저장된 Shellcode 실행 가능

1.5 Proof of concept2

1) poc.c: vuln() 함수가 read() 함수를 이용해 사용자로부터 100개의 문자를 입력받음. buf 변수의 크기는 50byte이기 때문에 Stack Overflow 발생

2)

0x400566: vuln 함수의 첫번째 명령어
0x400595: read() 함수의 호출
0x40059c: vuln() 함수의 ret 명령어

rsp 레지스터가 가리키고 있는 최상위 Stack 메모리는 0x7fffffffdea8
해당 메모리에 vuln() 함수 종료 후 돌아갈 코드 영역의 주소 값(0x4005ab)이 저장되어 있음

buf 변수의 위치는 0x7fffffffde60이며, Return address 위치와 72byte 떨어져 있음.
사용자 입력 값으로 문자를 72개 이상 입력하면 Return address를 덮어쓸 수 있음

0x7fffffffdea8 영역에 0x4848484848484848이 저장됨. 72개의 문자를 입력 후 Shellcode가 저장된 주소를 저장하면 Return address를 덮어쓸 수 있음

3) exploit

Exploit code

Shell

0개의 댓글