2025. 1. 28. 17:42ㆍWARGAME/CTFLEARN
포너블 문제입니다.
BOF는 Buffer Over Flow로 버퍼 오버플로우의 약자입니다.
bof는 메모리를 다루는 데에 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점이다.
먼저 bof.c 소스 코드를 확인합니다.
코드를 먼저 확인하는 이유는 문제 서버를 보지 않고 어떤 문제인지 파악하는 연습을 하기 위함입니다 ㅎㅎ
c언어 너무 오랜만......
패딩 크기는 16byte, 버퍼 크기는 32byte입니다.
secret 값이 0x67616c66이 되면 플래그 값을 출력합니다.
notsecret값이 0xffffff00이 아니거나
secret 값이 oxdeadbeef에서 바뀌었지만 정답이 아니면
에러 메시지가 출력됩니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// Defined in a separate source file for simplicity.
void init_visualize(char* buff);
void visualize(char* buff);
void safeguard();
void print_flag();
void vuln() {
char padding[16];
char buff[32];
int notsecret = 0xffffff00;
int secret = 0xdeadbeef;
memset(buff, 0, sizeof(buff)); // Zero-out the buffer.
memset(padding, 0xFF, sizeof(padding)); // Zero-out the padding.
// Initializes the stack visualization. Don't worry about it!
init_visualize(buff);
// Prints out the stack before modification
visualize(buff);
printf("Input some text: ");
gets(buff); // This is a vulnerable call!
// Prints out the stack after modification
visualize(buff);
// Check if secret has changed.
if (secret == 0x67616c66) {
puts("You did it! Congratuations!");
print_flag(); // Print out the flag. You deserve it.
return;
} else if (notsecret != 0xffffff00) {
puts("Uhmm... maybe you overflowed too much. Try deleting a few characters.");
} else if (secret != 0xdeadbeef) {
puts("Wow you overflowed the secret value! Now try controlling the value of it!");
} else {
puts("Maybe you haven't overflowed enough characters? Try again?");
}
exit(0);
}
int main() {
setbuf(stdout, NULL);
setbuf(stdin, NULL);
safeguard();
vuln();
}
29line의 gets()함수가 취약한 부분입니다.
gets()함수는 입력을 받을 때 길이 제한이 없다.
그렇기에 입력값이 buff 크기인 32byte를 초과하면 스택 오버플로우가 발생하게 됩니다.
0x67616c66값을 문자열로 넣어줘야 하기 때문에 텍스트로 변환해줍니다.
galf 는 flag를 거꾸로 한 문자열이고
리틀엔디안 방식으로 flag 문자열을 입력해주면 0x6716c66값이 됩니다.
nc로 문제 서버에 접속해봅니다.
스택을 보여주는데 친절하게 색으로 바이너리를 보여줍니다.
초록색은 buff 영역이며, 버퍼 크기는 32byte입니다.
노란색은 padding값이고,
파란색은 notsecret
빨간색은 secret 입니다.
버퍼 > 패딩 > secret > notsecret 순서로 스택이 이뤄져있습니다.
secret 값을 flag로 바꿔야하고 그 notsecret 값은 건드리면 안됨을 주의해야 합니다.
처음은 flag 문자열로 변경을 확인해보았습니다.
처음 4byte가 00 00 00 00 에서 66 6c 61 67로 바뀌었습니다.
이로써 buff 크기와 패딩 크기 만큼을 입력 값으로 채운 뒤 flag를 입력하면 0xdeabeef를 0x67616c66으로 바꿀 수 있음을 알 수 있습니다.
버퍼 크기는 32byte + 패딩 크기는 16byte
따라서 48byte를 입력한 뒤 flag를 입력해주면 secret값만 변경할 수 있습니다.
48byte는 a로 채워주고 flag를 입력해주었습니다.
CORRECT secret값과 일치하면서 플래그 값이 출력되었습니다.
'WARGAME > CTFLEARN' 카테고리의 다른 글
[forensics] Forensics 101 - steganography (0) | 2025.01.30 |
---|---|
[crypto] Base 2 2 the 6 - base64 (0) | 2025.01.29 |
[forensics] Taking LS - hidden file (0) | 2025.01.28 |
[misc] QR Code - QR / Base64 / ROT13 (0) | 2025.01.28 |
[crypto] Character Encoding - ASCII (0) | 2025.01.28 |