버퍼 오버플로우에 대해서 공부하게 되는 attack lab이다.
이 랩을 해결하기 위해서는 몇 가지 지식이 결합되어야하는데 이는 CS:APP 책에 모두 나온다.
첫째는 리틀인디언, 빅인디언이다. getbuf 함수를 이용해서 버퍼 오버 플로우를 유도해야하는데 어떤 순서로 cpu가 명령을 읽는지 데이터를 읽는지 에대한 지식이 필요하다. 두 번째는 스택포인터와 PC에 대한 개념이다. 어셈블리의 retq와 스택포인터의 현 주소를 이용해 PC와 스택포인터를 내가 원하는대로 조종해야 한다. 이 정도 지식이 있다면 phase_3까지는 해결할 수 있다. phase_4, 5 를 해결할 수 없다는 뜻은 아니다. 내가 phase_3까지 해결했기에 그렇게 말할 뿐이다.
먼저 call 해야하는 함수의 종류와 몇 개와 어떤 인자를 받고 있는지 알아야할 필요가 있다. touch3 는 sval 이라는 char*를 인자로 받고 다시 hexmatch는 쿠키와 sval을 인자로 받는다. hexmatch 의 역할은 간단하다. 쿠키는 0x12345678 같은 16진수로 이루어져 있는데 여기서 12345678을 string으로 인식하고 이를 char*의 값인 sval과 비교해서 일치하면 0을 반환한다. touch3를 보면 0을 반환해야 올바르게 attack이 이루어지기 때문에 0을 유도해야한다. 그러면 어떻게 0을 유도할까???
간단하다. rdi레지스터가 각각 1 2 3 4 5 6 7 8 바이트 코드로보면 31 32 33 34 35 36 37 38 00 으로 스트링 값을 가지게 하면 된다.
그런데 여기서 한 가지 주의사항이있다. 맨 처음 getbuf에서 스택포인터를 0x28만큼 증가시켜준다. 그 후 touch3나 hexmatch 함수를 call 할 때 또 다시 스택포인터를 증가시키게되는데(스택포인터에서 값을 빼주는 방식으로) 이 할당할 때 내가 rdi 레지스터가 가르키게 하는 값을 overwrite하면 안된다.
그럼 스택포인터의 값을 gdb 디버거 i r 명령어로 알아낸 후에 리턴 주소를 스택포인터로 바꾸어주고 그 다음에 rdi가 가르킬 주소 값을 어셈블리를 gcc를 이용해 목적코드를 넣어주고 이 rdi가 가르킬 값들을 0verwrite 되지 않을 범위에 넣어주면된다.
여기서 getbuf가 0x28 만큼 할당했다고 가정한다.
31 32 33 34 35 36 37 38 //rdi가 가르킬 쿠키의 값
00 00 00 00 00 00 00 00 //의미없는 값
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
48 c7 c7 78 dc 61 55 c3 //위에 rdi가 가르킬 쿠키의 값의 주소
98 dc 61 55 00 00 00 00 //바로 윗 줄 명령어를 실행하게 할 return 주소
fa 18 40 00 00 00 00 00 // touch3를 실행시킬 return 주소
스크린 샷이 없어서 추상적으로 보일 수 있겠지만 lab과제를 하는 사람들에게 가이드라인이 될 수 있으면 좋겠다.
어택 랩은 pc와 스택포인터의 역할 그리고 버퍼오버플로우를 잘 이해할 수 있는 좋은 과제다.
'공부 일지' 카테고리의 다른 글
CS:APP Bomb lab Phase_5 풀이 (0) | 2018.07.11 |
---|---|
CS:APP Bomb lab Phase_4 풀이 (0) | 2018.07.11 |
CS:APP 3장 Machine Level Reprentation of Programs (0) | 2018.07.09 |