Stack Canary : 스택 버퍼 오버플로우로부터 반환 주소를 보호한다.
함수의 프롤로그에서 스택 버퍼와 반환 주소 사이에 임의의 값을 삽입하고,
함수의 에필로그에서 해당 값의 변조를 확인하는 보호 기법.
카나리 값의 변조가 확인되면 프로세스 강제 종료.
스택 버퍼 오버플로우로 반환 주소를 덮으려면 반드시 카나리를 먼저 덮어야 한다.
gcc -o no_canary canary.c -fno-stack-protector
-fno-stack-protector 옵션을 추가해야 카나리 없이 컴파일 할 수 있다.
근데 이 문제에는 카나리는 없다.
대신 NX가 있다.
NX(DEP)
NX와 DEP는 같은 개념의 보호기법이다.
Non executable, Data Execution Protection의 약자.
'heap과 stack같이 bof 공격에 이용되는 메모리 공간에 있는 코드를 실행시키지 않는다'는 뜻.
그럼 이 문제는 buf에 쉘 코드를 입력하는 게 아니라 플래그와 관련있는 함수를 실행시켜야한다는 걸로 볼 수 있다.
PIE가 적용되지 않기 때문에, read_flag 함수 주소는 고정값이다.
*NX OFF*
gcc -m32 -mpreferred-stack-boundary=2 -z execstack -fno-stack-protector nx.c -o nxOFF
*NX ON*
gcc -m32 -mpreferred-stack-boundary=2 -fno-stack-protector nx.c -o nxON
PIE(Postition Independent Executable)
위치 독립 실행.
일반 실행파일은 정해진 주소에 코드가 위치한다.
PIE 파일은 주소가 정해져있지 않고 새로 실행할 때마다 바뀐다.
다운받은 c언어 파일을 cat으로 열어봤다.
30초 안에 입력값이 주어지지 않으면 TIME OUT을 출력하면서 강제종료되는 것으로 보인다.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
read_flag 함수에 접근해야 시스템이 플래그 파일을 열어서 보여주는 것 같다.
전에 풀었던 basic000 문제 처럼 bof를 이용해야 할 것 같다.
gets 함수가 buf를 입력받을 때 입력 길이 제한을 해두지 않았으니 이건 bof를 이용하라는 걸로 볼 수 있다.
128바이트보다 크게 입력값을 주는데 buf와 sfp를 모두 덮는데 132바이트 크기가 필요하니 남은 4바이트를 read_flag 함수의 주소로 채워 주면 되지 않을까?
pwndbg로 메인 함수와 플래그 함수를 디스어셈블 해봤다.
read_flag 함수의 주소는 0x1217이다.
함수 주소를 0x1217로 해서 입력했는데 플래그가 안 나오길래 write up 참고해서 나온 주소를 입력하니 그제서야 플래그가 출력됐다.
뭐가 문제인건지 모르겠다.
'시스템 해킹' 카테고리의 다른 글
4주차 질문 (0) | 2022.08.19 |
---|---|
gdb 개념 및 사용법 (0) | 2022.08.19 |
pwnable.kr bof 문제 풀이 (0) | 2022.08.19 |
Stack Overflow (0) | 2022.08.18 |
gdb 분석 실습 (0) | 2022.08.18 |