01. BOF란?
버퍼에 허용할 수 있는 양의 데이터보다 더 많은 값이 저장되어 버퍼가 넘치는 취약점
02. 소스 코드 분석
먼저 살펴볼 것은 win() 함수이다. flag를 출력하는 함수로 우리는 이 함수가 실행되게 해야한다.
void win () {
char flag[100] = {0,}; //flag 버퍼을 100byte만큼 0으로 채운다
int fd;
puts ("You mustn't be here! It's a vulnerability!");
fd = open ("./flag", O_RDONLY); //flag 파일을 읽기 모드로 열기
read(fd, flag, 0x60); //open으로 연 파일을 참조, flag 파일을 최대 96byte 데이터를 읽어 flag 버퍼에 저장
puts(flag); //flag 버퍼 출력
exit(0);
}
이제 main함수 내부로 진입하자. 16바이트 버퍼 name이 선언되었다.
char name[16]; //16byte 버퍼로 총 16개의 char(1byte)를 저장할 수 있음
int age[20] ;
=> 20개의 int형(4바이트) 데이터를 연속으로 저장할 수 있는 80바이트짜리의 연속된 메모리 버퍼를 만드는 선언
0x%lx => 0x(16진수), %lx(unsigned long)을 16진수(x)로,,,라는 의미이다. 그리고 c에서는 함수 이름 자체가 해당 함수의 시작 주소를 의미하기에 win을 printf에 넘김으로서 win 함수의 메모리 주소를 출력할 수 있다.
printf ("the main function doesn't call win function (0x%lx)!\n", win); //win 함수의 주소값을 출력
scanf함수의 %s는 입력 길이를 제한하지 않으며 공백 문자가 들어올 때까지 계속 입력을 받기에 오버플로우가 발생할 수 있다(사용하면 안됨).
printf ("name: ");
scanf ("%15s", name); //%s(string)으로 name을 15바이트만큼 받아오기
idx는 for문을 돌면서 0~16(0x10) 전까지 증가하여 총 16번 실행된다. name + idx *8는 name(name 주소)에 idx *8을 더한 값으로 long타입 16진수(%lx)로 출력된다. name+8, name+16,...으로 8바이트씩 주소가 출력되는 것이다. *(long*)(name + idx*8)는 name+8, name+16 주소를 포인터로 참조하여, 해당 주소에 적힌 값을 16폭으로 long타입 데이터를 16진수로 출력한다.
printf ("GM GA GE GV %s!!\n: ", name); //우리가 입력한 name을 %s로 출력
printf ("| addr\t\t| value\t\t|\n");
for (idx = 0; idx < 0x10; idx++) {
printf ("| %lx\t| %16lx\t|\n", name + idx *8, *(long*)(name + idx*8));
}
나는 name에 d를 입력했는데 d는 아스키코드로 나타내면 64이다. 그리고 15번 d를 입력해서 value값을 보면 64가 15개 있는걸 볼 수 있다. 그리고 name 주소값에서 시작했기 때문에 2번째 라인까지는 name의 값이 저장되는 주소인것을 알 수 있다.

이후 사용자로부터 value와 count를 입력 받는다.
printf ("hex value: ");
scanf ("%lx%c", &value);
printf ("integer count: ");
scanf ("%d%c", &count);
그리고 입력받은 value와 count값을 기반으로 아래 코드가 실행된다. value값으로 입력한 값이 *(long*)(name+idx*8)에 저장된 값을 덮어 쓴다는 의미이다. 여기서 BOF를 터트릴 수 있다. value에 win() 함수의 주소를 저장해두면 return시 win함수의 주소로 이동하여 win 함수가 실행되도록 할 수 있기 때문이다.
for (idx = 0; idx < count; idx++) {
*(long*)(name+idx*8) = value;
}
for (idx = 0; idx < 0x10; idx++) {
printf ("| %lx\t| %16lx\t|\n", name + idx *8, *(long*)(name + idx*8));
}

'Wargame' 카테고리의 다른 글
| [Beginner] bof (0) | 2025.11.10 |
|---|---|
| Zipper (0) | 2025.01.10 |
| Windows Search (0) | 2025.01.06 |
| Basic_Forensics_1 (0) | 2025.01.06 |
| session-basic[web] (0) | 2024.12.28 |