프레임 포인터 오버라이팅 기법에 대해 알아보자.
fake ebp 하위 개념이라고 생각하면 된다.
프레임 포인터 오버라이팅은
RET 위로 덮어쓸 수 없을 때, 1바이트 오버플로우가 가능하다면
공격이 가능한 기법이다. 흔히 1byte overflow 라고도 한다.
하지만 조건이 있다.
1. 1바이트 오버플로우가 일어나야 한다.
2. 메인함수 외에 서브함수가 반드시 필요하다.
그럼 프레임 포인터 오버라이팅에 대해 알아보자.
문제점이 생기는 소스코드를 예제로 하나 보여주지.
function(char *arg) { char buffer[80]; int count; for(count=0;count<=80;count++) buffer[count]=arg[count]; }
main(int argc, char *argv[])
{ function(argv[1]); }
위 코드를 보면 초보(?)개발자 들이 흔히 실수할 수 있는 부분이다
버퍼의 크기가 80인데 for 루프를 0~80 즉, 81번 돈다.
이러면 버퍼 위의 SFP 부분의 1바이트가 오버플로우 된다.
그렇게 되면 에필로그(leave-ret)시에 ebp 레지스터를 조작할 수 있게 된다.
뭔말인지 헷갈린다. 역시 우리는 그림이 필요하다.
메인 함수 프롤로그 후 서브 함수가 호출 되고,
서브 함수의 에필로그 시에 페이로드를 올리는 스택 상황이다.
아까 말했듯이 1바이트가 오버플로우 된다고 했다. 그럼 주소를 조정할 수 있겠지.
뭐 조작해봐야 0xbfffff○○ 이 범위 안이지만..
(그림을 보기 전에 내가 살짝 오해의 소지를 살만하게 설명을 해놨는데, &Shellcode-4 라고 되있는 부분은
셸코드의 주소값 -4 가 아니라 셸코드의 주소값이 있는 곳의 주소 -4이다.)
일단 페이로드를 저런식으로 올린다. 셸코드는 다른 곳에 있다고 가정합시다.
자 그럼 이제 서브함수의 에필로그가 끝나고 메인함수로 돌아가
메인 함수의 에필로그 과정에 어떻게 스택이 변화하는지 보자.
fake ebp와 다른 거라면 leave-ret 가젯을 쓰는 대신 함수 에필로그가 두번 쓰인다는 것..
1번째 -> 2번째 그림 : leave 명령이 수행되어 ebp는 '??' 즉, 알 수 없는 주소로 떠내려간다.
2번째 -> 3번째 그림 : ret 명령이 수행되며 shellcode가 실행된다.
leave-ret 명령어를 보면서 하나씩 따라가다 보면 쉽게 이해할 수 있다.
마지막 ret이 수행되면서 shellcode 주소를 eip가 가르키면서 공격은 끝.
그렇다면
fake ebp와 비슷한 개념인데, 무엇이 다를까?
일단 fake ebp는 서브 함수가 없어도 된다. leave-ret 가젯을 이용할 수 있기 때문이다.
프레임 포인터 오버라이트는 1바이트 밖에 변조가 되지 않으므로 RET을 원하는 값으로 변조할 수 없다.
대신에 에필로그(leave-ret) 를 한번더 일어나게 하기 위해 서브 함수가 필요한 것임.!
'IT 그리고 정보보안 > Knowledge base' 카테고리의 다른 글
RTL Chaining으로 커스텀 스택(.bss)에 문자열 저장 (0) | 2021.04.15 |
---|---|
RTL Chaining (esp lifting technique) (0) | 2021.04.15 |
Fake EBP (0) | 2021.04.15 |
RTL(bypass NX-bit, ASCII Armor) (0) | 2021.04.15 |
RET Sled (0) | 2021.04.15 |