1. 풀이

- hint 파일의 내용을 보면, 256byte의 str 배열 선언 후, level13의 권한 부여 및 gets()로 사용자에게 입력을 받음

- gets()에는 다음과 같은 취약점이 존재함

- 즉,  256byte의 크기를 지니고 있음에도 불구하고, gets()는 문자열의 길이를 검사하지 않고 문자열을 입력므로, BOF(버퍼 오버플로우)에 취약한 함수

- attackme 파일을 tmp로 복사한 후 gdb로 attackme 파일을 분석해보면 다음과 같음

 

① Procedure Prelude

0x08048473 <main+3>:    sub    $0x108,%esp

- 지역변수에 0x108(264) 만큼의 공간을 할당

- str 배열의 크기는 256byte이므로 8byte 만큼의 dummy가 존재하는 것을 알 수 있음

 

② setreuid(0xc15,0xc15)

0x0804847c <main+12>:   push   $0xc15
0x08048481 <main+17>:   push   $0xc15
0x08048486 <main+22>:   call   0x804835c <setreuid>

- level13의 권한 부여

 

③ gets(문자열이 저장될 배열);
0x080484a1 <main+49>:   lea    0xfffffef8(%ebp),%eax
0x080484a7 <main+55>:   push   %eax
0x080484a8 <main+56>:   call   0x804831c <gets>

- gets()를 이용해 사용자로부터 입력을 받음

- gets()는 문자열을 담을 공간의 길이와 입력받은 문자열의 길이를 확인하지 않고 입력을 받으므로 BOF에 취약

- gets()로 입력을 받을 때, str+dummy+SFP를 덮을 수 있는 충분한 \x90와 쉘코드의 주소를 인자로 전달할 경우 RET 값이 쉘코드를 저장하고있는 주소로 변조되어 쉘코드가 실행됨

- 쉘코드를 환경변수로 선언 및 환경변수의 주소 확인

- NOP를 268개(str(256byte)+dummy(8byte)+SFP(4byte)) + Little-Endian환경변수 주소를 인자로 attackme 실행

- 쉘이 실행되지 않아 구글조회 결과 cat 명령과 | 을 이용해 프로그램을 실행해야함

- Pipe(|) 사용 시 Pipe 기준으로 왼쪽 프로그램의 결과가 오른쪽 프로그램의 입력으로 전달되는데, python이 실행되고 종료되면서 broken pipe 오류로 인해 종료가 발생함

- 따라서 사용자의 입력을 출력해주는 cat이나 te를 이용하여 stdin을 유지 시켜야함

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level14 풀이  (0) 2022.11.05
FTZ Level13 풀이  (0) 2022.11.04
FTZ Level11 풀이  (0) 2022.10.31
FTZ Level10 풀이  (0) 2022.10.31
FTZ Level9 풀이  (1) 2022.10.30

1. 풀이

- hint 파일의 내용을 보면, 256byte의 str배열을 선언한 후, setreuid()로 level12의 권한을 부여한 후 문자열 복사 및 출력을 수행

- strcpy()에는 다음과 같은 취약점이 존재함

- 즉, str 배열은 256byte의 크기를 지니고 있음에도 불구하고, strcpy()는 문자열의 길이를 검사하지 않고 NULL 문자를 만나기 전까지의 문자열을 복사하므로, BOF(버퍼 오버플로우)에 취약한 함수

- attackme 파일을 tmp로 복사한 후 gdb로 attackme 파일을 분석해보면 다음과 같음

 

① Procedure Prelude

0x08048473 <main+3>:    sub    $0x108,%esp

- 지역변수에 0x108(264) 만큼의 공간을 할당

- str 배열의 크기는 256byte이므로 8byte 만큼의 dummy가 존재하는 것을 알 수 있음

 

② setreuid(0xc14,0xc14)

0x0804847c <main+12>:   push   $0xc14
0x08048481 <main+17>:   push   $0xc14
0x08048486 <main+22>:   call   0x804834c <setreuid>

- level12의 권한 부여

 

③ strcpy(복사할 대상, 복사할 원본);

0x08048497 <main+39>:   pushl  (%eax)
0x08048499 <main+41>:   lea    0xfffffef8(%ebp),%eax
0x0804849f <main+47>:   push   %eax
0x080484a0 <main+48>:   call   0x804835c <strcpy>

- strcpy()를 이용해 argv[1]의 값을 str 배열에 복사를 수행

- strcpy()는 문자열 길이에 대한 검증을 수행하지 않기에 BOF에 취약

- 즉, argv[1]에 쉘코드를 전달하면 strcpy()의 취약점으로 인해 쉘코드까지 복사되어 쉘코드가 수행

- 따라서, RET에 str 배열의 시작 주소를 전달하면, 쉘코드를 수행할 수 있음

 

④ printf(str)

0x080484b1 <main+65>:   push   %eax
0x080484b2 <main+66>:   call   0x804833c <printf>

- str 출력

 

- str의 시작 주소를 알기위해 strcpy() 수행 후인 <main+53>에 BP(브레이크 포인트)를 설정한 후 인자를 전달

- 하지만 ASLR이 적용되어 있어 매번 주소값이 변경됨

ASLR (Address Space Layout Randomization)
- 주소의 공간을 무작위로 변경하는 기법
- 데이터, 스택, 힙 영역의 주소를 무작위로 변경하는 기법
- 따라서 환경변수의 주소 값을 매 실행마다 다르게 하여 원하는 값이나 주소를 가져오지 못하도록 만드는 기술

- 해당 기법을 우회 하기위해 RET에 쉘코드가 저장된 환경변수의 주소를 전달하면, 쉘 코드를 수행할 수 있게됨

- 먼저 공격에 사용할 쉘코드가 저장된 환경변수를 선언

- 해당 쉘코드는 가장 기본적으로 쉘을 띄우는 25byte의 쉘코드

\x90
- NOP(No OPeration)
- 프로그램의 실행에 영향을 주지 않는 명령어
- 프로그램이 실행 중에 NOP 명령어를 만나면 아무런 동작없이 다음 명령어로 넘어가게됨
- 쉘코드의 시작주소를 정확히 알지 못하더라도 NOP를 통해 쉘코드를 실행시킬 수 있으며, 이를 NOP SLED 기법이라함

- 다음으로, 해당 코드를 사용해 환경변수의 주소를 확인

- NOP를 268개(str(256byte)+dummy(8byte)+SFP(4byte)) + Little-Endian환경변수 주소를 인자로 attackme 실행

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level13 풀이  (0) 2022.11.04
FTZ Level12 풀이  (0) 2022.10.31
FTZ Level10 풀이  (0) 2022.10.31
FTZ Level9 풀이  (1) 2022.10.30
FTZ Level8 풀이  (0) 2022.10.30

1. 풀이

-  7530을 key로 가지는 공유메모리의 값을 읽어야 하는 문제로 판단됨.

공유메모리
- 여러 프로그램이 메모리를 공유
- 공유한 메모리를 통해 데이터를 주고 받음
- 명령 : ipcs 

- ipcs 명령으로 공유메모리를 확인해보면 0x00001d6a(10진수 7530)를 key로 가지는 공유메모리가 확인됨

- 공유메모리 관련 함수

① shmget(key_t key, int size, int shmflg) : 공유메모리 생성 또는 생성된 공유메모리 사용
- key_t key : 공유메모리를 읽기 위한 key 변수
- int size : 공유 메모리의 크기
- int shmflg : 공유메모리 생성이나 사용 옵션을 지정
     => IPC_CREAT : 공유메모리가 없을 경우 생성, 이미 존재한다면 접근권한 명시
     => IPC_EXCL : 공유메모리가 이미 있다면 실패로 반환하고 공유메모리에 접근 불가능

② shmat(int shmid, const void xshmaddr, int shmflg) : 이미 할당된 공유메모리 공간을 다른 프로세스에서 사용할 수 있게 권한 부여
- int shmid : 공유메모리를 생성할 때 만들어진 공유메모리의 ID
- const void xshmaddr : 공유메모리가 할당 된 주소
- int shmflg : 공유메모리 사용 옵션
     => SHM_RDONLY : 읽기 전용
     => SHM_RND : 공유 메모리 주소를 프로세스에 맞게 따로 할당

③ shmdt(const void xshmaddr) : 프로세스와 공유메모리공간의 연결 종료
- const void xshmaddr : 공유메모리가 할당 된 주소

 

- 위 함수를 사용한 공격코드 작성 후 컴파일하여 실행 시 비밀번호 확인이 가능함

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(int argc, char **argv) {
    key_t key;
    int shmid;
    void *shmbuf;
    char buf[1028];

    key = 0x1d6a; // 7530
    shmid = shmget(key, 1028, 0);

    shmbuf = shmat(shmid, NULL, 0);
    printf("%s\n", shmbuf);
    system("ipcs -m");
    shmdt(shmbuf);

    return 0;
}

출처 : https://domdom.tistory.com/entry/FTZ-level10-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4Writeup-%ED%95%B4%EC%BB%A4%EC%8A%A4%EC%BF%A8Hackerschool

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level12 풀이  (0) 2022.10.31
FTZ Level11 풀이  (0) 2022.10.31
FTZ Level9 풀이  (1) 2022.10.30
FTZ Level8 풀이  (0) 2022.10.30
FTZ Level7 풀이  (0) 2022.10.28

1. 풀이

- hint 내 작성된 소스를 통해 버퍼 오버플로를 이용해 문제를 풀어야 하는것을 추측해볼 수 있음

버퍼 오버플로우(Buffer Overflow)
- 메모리를 다루는 데에 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점으로 시스템 해킹의 대표적인 공격 방법 중 하나
- 데이터가 지정된 크기의 공간보다 커서 해당 메모리 공간을 벗어 나는 원래 의도와 다르게 동작하도록 유도하는 공격 유형

- /usr/bin/bof를 실행해 아무런 값을 입력해 보았으나, 변화 없음

- gdb로 디버깅을 시도 하였으나, level9 사용자는 해당 파일에 대해 실행권한만 있어 gdb로 파일을 읽을 수 없음

- hint 파일의 소스코드를 새로운 파일에 복사 및 컴파일하여 gdb로 분석 수행

- gdb를 통해 bof를 분석해보면 다음과 같음

 

① Procedure Prelude 수행

- 함수로 진입하면서 함수로 진입하기 전의 스택 포인터(SP)의 위치를 저장한 다음 변수로 사용할 공간을 확보하는 과정

- 즉, 함수 진입 전 리턴주소(RET)와 스택 포인터(SFP)를 저장하여, 함수 수행이 끝난 후 원래 위치로 돌아가기 위해 진행되는 과정

- 1번 과정에서는 RET(4yte)>SFP(4byte)>지역변수(0x28 = 40) 순으로 스택에 저장

 

② fgets(배열, 문자 길이, STDIN)

0x08048443 <main+35>:   pushl  0x8049698 // STDIN
0x08048449 <main+41>:   push   $0x28 // 문자길이 (0x28 = 40)
0x0804844b <main+43>:   lea    0xffffffd8(%ebp),%eax // 0xffffffd8 (buf의 주소)
0x0804844e <main+46>:   push   %eax // buf 주소
0x0804844f  <main+47>:   call   0x8048320 <fgets>

- 즉, fgets()를 통해 0xffffffd8 (buf 주소)에 사용자 입력값을 받음

 

③ strncmp(문자열1, 문자열2, 비교할 문자의 갯수)

0x0804845a <main+58>:   push   $0x2 // 0x2 
0x0804845c <main+60>:   push   $0x804856a // go
0x08048461 <main+65>:   lea     0xffffffe8(%ebp),%eax // 0xffffffe8 (buf2 주소)
0x08048464 <main+68>:   push   %eax // buf2 주소
0x08048465 <main+69>:   call   0x8048330 <strncmp>

- 즉, strncmp()를 통해 0xffffffe8 (buf2 주소)부터 2byte 값을 문자열 go와 비교

- ②와 ③을통해 buf 주소(0xffffffd8)와 buf2 주소(0xffffffe8)간 차이는 16byte을 알 수 있으므로, buf와 buf2 사이에 6byte 만큼의 dummy 값이 존재하는 것을 알 수 있음

- 또한, buf2와 SFP 사이에도 dummy 값이 존재하며, 그 크기는 14byte

 

④  문자열 비교 후 수행 순서 결정

0x0804846d <main+77>:   test   %eax,%eax
0x0804846f <main+79>:   jne    0x80484a6 <main+134>

- 두 값을 비교해(if문) 결과가 참일 경우, 즉 문자열이 일치할 경우 level10의 권한 설정(setreuid(3010,3010)) 및  level10의 권한으로 bash를 실행(system("bin/bash"))

- 결과가 거짓일 경우, 즉 문자열이 일치하지 않을 경우 <main+134>로 점프하여 프로그램 종료

 

- buf2에 문자열 go를 입력하기 위해서는 16byte(buf 10byte + dummy 6byte) 만큼의 문자열이 필요함

- 프로그램 실행 후 위 사진과 같이 값을 입력할 경우 버퍼 오버플로가 발생해 결과적으로 buf2에 go가 입력되어 level10의 권한으로 bash를 실행할 수 있음

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level11 풀이  (0) 2022.10.31
FTZ Level10 풀이  (0) 2022.10.31
FTZ Level8 풀이  (0) 2022.10.30
FTZ Level7 풀이  (0) 2022.10.28
FTZ Level6 풀이  (1) 2022.10.28

1. 풀이

- find 명령의 -size 옵션을 통해 해당 파일 검색

옵션 설명
-size 옵션 - 파일 크기를 기준으로 검색
- find / -size +[volume] > [volume] 이상 크기의 파일을 검색
- find / -size -[volume] > [volume] 이하 크기의 파일을 검색
- find / -size [vloume] > [volume]  크기의 파일을 검색
- 단위 : b : 블록 / c : 바이트 / k : 키로바이트 / w : 2바이트 워드 / m : 메가 바이트 / g : 기가 바이트 단위

- 우선, 가장 간단한 텍스트 파일인 etc/rc.d/found.txt 파일을 열어보면 ":"로 구분된 문자열이 출력

- hint 파일을 통해 shadow 파일이 문제 해결과 관련된 것을 알 수 있으며, 따라서 /etc/rc.d/found.txt 파일은 /etc/shadow 파일임을 추측해 볼 수 있음

/etc/shadow
- 기존에는 계정정보를 /etc/passwd에 기록 (비밀번호 평문 저장)
- 기술의 발전으로 비밀번호 크랙 가능성이 높아짐에따라 비밀번호 정보를 /etc/shadow 파일에 저장
- /etc/passwd 파일의 비밀번호 필드 값이 x로 표시된 경우 /etc/shadow 파일 사용
- 필드 값 및 각 필드의 의미는 다음과 같음
name:encrypted_password:last_password_change:minimum:maximum:warning:inactivity:expiration
① name: 계정명
② encrypted_password: 암호화된 패스워드
③ last_password_change: 마지막으로 비밀번호를 변경한 날. 1970/01/01부터 일수로 계산.
④ minimum: 최소 비밀번호 사용 일수
⑤ maximum: 최대 비밀번호 사용 일수
⑥ warning: 비밀번호 만료 전 경고 일수
⑦ inactivity: 비밀번호가 만료된 후 유예기간
⑧ expiration: 계정 자체의 만료 기간. 1970/01/01부터 일수로 계산.

- /etc/shadow 파일의 2번째 필드 값인 암호화된 패스워드는 다시 $id$salt$hashed 3부분으로 나눌 수 있음

필드 적용 알고리즘 설명
$id $1 MD5 비밀번호 일방향 암호화 시 적용한 해싱 알고리즘
$2a Blowfish
$2y Eksblowfish
$5 SHA-256
$6 SHA-512
$salt 임의의 난수 해싱에 사용된 솔트(salt)값
$hashed Hash(비밀번호) 해싱된 비밀번호 값

- /etc/shadow 파일에서 비밀번호를 크랙해내기 위해 Jone the ripper를 활용

Jone the ripper
- https://www.openwall.com/john/에서 맥, 리눅스, 윈도우 버전을 다운 가능함
- 암호화된 비밀번호를 크래킹할 수 있는 도구

- /etc/rc.d/found.txt 파일의 내용을 칼리 리눅스에 임의의 파일명으로 저장 후 명령을 통해 패스워드 크랙이 가능함

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level10 풀이  (0) 2022.10.31
FTZ Level9 풀이  (1) 2022.10.30
FTZ Level7 풀이  (0) 2022.10.28
FTZ Level6 풀이  (1) 2022.10.28
FTZ Level5 풀이  (0) 2022.10.27

1. 풀이

- /bin/level7을 실행하면 비밀번호를 입력해야하며, 아무 값이나 입력해보니 /bin/wrong.txt 파일이 없다는 에러가 출력

- 하지만, 해당 파일은 확인되지 않음

- 이는 개인이 FTZ 서버를 열어서 하는 경우 생기는 에러로, 직접 root 계정으로 접속해 wrong.txt를 생성해 주어야 함.

- su 명령으로 root 계정에 로그인 후 해당 파일을 생성하고, 재접속 시 정상 실행됨.

- hint 파일에서 얻은 내용으로 다음을 유추해 볼 수 있음

① 상상력을 총동원하라 > 비밀번호 입력후 나타나는 문자열이 모스부호임을 추측

② 2진수를 10진수를 바꿀 수 있는가? > - 와 _를 각각 1 또는 0으로하여 2진수를 만든 후 10진수로 변환

① - : 1, _ : 0 인 경우
1101101 1100001 1110100 1100101 > 109 97 116 101

② - :0, _ : 1 인 경우
0010010 0011110 0001011 0011010 > 18 30 11 26

- 10진수로 변환한 결과를 통해 아스키코드 값임을 유추해 볼 수 있음

- ①의 경우 mate, ②의 경우 DC2(제어문자) RS(제어문자) VT(공백문자) SUB(제어문자)로 ①이 비밀번호로 추측해볼 수 있음

2. GDB를 통한 의사 코드 복원

- malloc>printf>fgets

- malloc()으로 0x64만큼의 메모리를 할당받고, Insert ~ 구문을 출력한 후 fgets()로 사용자 입력을 받음

- strncmp>test>printf>exit>system

- 사용자가 입력한 비밀번호와 실제 비밀번호와 일치하는지 검증 후 검증 결과에 따라 다음 실행을 결정함

#include <stdio.h>

int main()
{
// 변수 선언
char pass="????";
char input;

input=(*char)malloc(0x64); // 0x64 메모리 할당

printf("Insert The Password : "); // 구문 출력

fgets(input,0x64,STDIN); // 사용자 입력

// 입력값과 비밀번호 비교
// strncmp(str1, str2, 비교 크기)
// str1 < str2 : 음수 반환
// str1 > str2 : 양수 반환
// str1 = str2 : 0 반환
if(strncmp(input,pass,0x4)==0) // 올바른 비밀번호 입력 시
{
// 구문 출력 후 종료
printf("\nCongratulation! next password is \"reak the world\".\n\n");
exit(0);
}
else // 잘못된 비밀번호 입력 시
{
system("cat /bin/wrong.txt");
}

free(input); // 할당받은 메모리 해제

return 0;
}

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level9 풀이  (1) 2022.10.30
FTZ Level8 풀이  (0) 2022.10.30
FTZ Level6 풀이  (1) 2022.10.28
FTZ Level5 풀이  (0) 2022.10.27
FTZ Level4 풀이  (0) 2022.10.27

1. 풀이

- level6은 이전의 level들과 달리 hint가 먼저 출력되며, 이 외의 내용은 확인되지 않음.

- 아무키를 입력하면 텔넷 접속 서비스가 나오며, bbs 선택 시 텔넷 연결 시도 메시지만 출력되며 다른 반응은 관찰되지 않음

- 연결 중지를 위해 ctrl + c (프로세스를 종료하는 인터럽트)를 입력하면, 종료됨.

- 텔넷 접속 서비스 화면에서 ctrl + c를 입력하면, "Can't use ctrl+c"라는 문구가 출력

- 초기 접속 화면에서 ctrl + c를 입력하면 level6의 홈 디렉터리에 접근

인포샵 bbs 텔넷
- 인포샵 bbs는 옛날 전화와 PC과 함께 통신하던 시절 이용되던 사설 BBS 서비스
- 사용자에게 주소를 입력 받아 ping 테스트 후 주소가 활성화 되어 있다면 연결해주는 서비스 제공
- 인포샵 bbs은 초기 접속 화면에서 Ctrl + C signal (프로그램 종료) 을 보내게 되면 바로 shell로 떨어지는 취약점을 가지고있음

- 홈디렉터리의 내용을 확인해보면 password 파일이 존재하며, 해당 파일에 접근하면 비밀번호를 확인할 수 있음.

- tn은 실행파일로, 실행 시 텔넷 접속 서비스를 제공하는 파일

2. GDB를 통한 의사 코드 복원

- fn 실행파일에 대한 분석

- system>getchar>system>printf 순으로 호출되며, signal 함수는 취약점을 이용하기 위한 함수로 판단됨.

- printf로 출력하는 구문을 봤을때, 텔넷 접속 서비스 화면이 출력되는 부분인 것을 알 수 있음.

- <main+190> ~ <main+197>은 signal 함수를 결정하는 부분

① 문법 : signal(시그널 번호, 시그널을 처리할 핸들)

② 해당 부분을 확인해 signal 함수를 완성하면 signal(2, sig_func)

③ 2번 신호는 SIGINT로, SIGINT가 입력되면 sig_func를 실행함 (SIGINT = ctrl+c)

- scanf()를 통해 사용자로부터 값을 입력 받아 비교한 후 결과에 따라 system 함수를 수행하고, 잘못된 값을 입력할 경우 프로그램 종료

#include <stdio.h>

int main()
{
// 변수 선언
char input;
int i,num;

system("cat hint"); // hint 내용 출력
input=getchar(); // 아무 입력 값 1개 받기
system("clear"); // 화면 초기화

// 구문 출력
printf("###########################\n");
printf("##                                       ##\n");
printf("##          텔넷 접속 서비스        ##\n");
printf("##                                       ##\n");
printf("##                                       ##\n");
printf("##      1. 하이텔    2. 나우누리    ##\n");
printf("##      3. 천리안                      ##\n");
printf("##                                       ##\n");
printf("###########################\n");

// signal()
if(i==SIGIN)
{
signal(i, sig_func);
}

printf("\n 접속하고 싶은 bbs를 선택하세요 : "); // 구문 출력

scanf(%d",&num); // 하이텔, 나우누리, 천리안 중 선택

switch(num) // 입력한 num에 따라 텔넷 연결 시도
{
case 1 :
system("telnet 203.245.15.76");

case 2 :
system("telnet 203.238.129.97");

case 3 :
system("telnet 201.120.128.180);

default :
if(num != 1 && num != 2 && num != 3)
{
printf(" 잘못 입력하셨습니다. 접속을 종료합니다. \n");
}
}
}

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level8 풀이  (0) 2022.10.30
FTZ Level7 풀이  (0) 2022.10.28
FTZ Level5 풀이  (0) 2022.10.27
FTZ Level4 풀이  (0) 2022.10.27
FTZ Level3 풀이  (0) 2022.10.25

1. 풀이

- hint 파일의 내용을 확인하면, /usr/bin/level5를 실행하면 /tmp/level5.tmp 임시파일을 생성함

- 심볼링 링크를 이용한 레이스 컨디션과 관련된 문제임을 유추가능

심볼릭 링크(Symbolic Link)
- 특정 파일이나 디렉터리에 대해 참조하는 파일로, 윈도우의 바로가기와 비슷한 개념
- 원본파일과 다른 inode를 가짐
- 심볼릭 링크 수정 시 원본 파일도 함께 수정
- 원본 삭제시 심볼릭 링크는 더 이상 사용할 수 없음
- 명령 : ln -s [원본] [심볼링 링크]

레이스 컨디션(Race Condition)
- 두 개의 프로세스/쓰레드가 하나의 자원을 접근하려고 할 때 경쟁하는 상태
- 실행 프로세스가 임시파일을 생성할 경우, 실행 중에 끼어들어 임시 파일을 목적 파일로 연결(심볼릭 링크)하여, 권한 상승(setuid를 이용) 등 악용하는 공격
- 단, 소유자가 root이고 SetUID가 설정된 프로그램이 생성하는 임시 파일 이름 및 경로를 알고 있어야함

- /usr/bin/level5를 반복 실행 및 /tmp/level5.tmp를 파일 A의 심볼릭 링크로 지정하여 공격을 시도

- 공격자가 생성산 임시파일 A가 자원 선점 경쟁에서 선점하게 될 경우 다음과 같은 시나리오가 발생

① /usr/bin/level5 실행

② 공격자의 심볼릭 링크 시도 ln -s A level5.tmp 및 자원 선점 발생

③ 임시파일 A 오픈

④ 임시파일 A 쓰기

⑤ 심볼릭 링크에 의한 원본 /tmp/level5.tmp에 쓰기 발생

⑥ 해당 프로그램(파일) 실행 종료

- /usr/bin/level5를 반복 실행하는 및 임시파일 Race Condition 코드 작성 후 컴파일, 실행

- 이후, tmp 디렉터리를 확인해보면 level6pass.txt 파일이 생성되었으며, 해당 파일을 통해 비밀번호를 알 수 있음

2. GDB를 통한 의사 코드 복원

- creat>print>remove 순으로 호출되며, cmpl을 통해 두 값을 비교하여 이후 실행 순서를 결정 

- create(file, 권한)으로 파일을 생성한 후 값 비교를 통해 이후 실행 순서를 결정하며, printf로 출력하는 구문을 보았을때, 임시파일 /tmp/level5.tmp가 이미 존재하는 파일일 경우 해당 파일을 삭제하고 실행을 종료하는 것을 추측가능함.

- write>close>remove 순으로 호출

- wirte() 함수로 파일에 작성되는 문자열을 보았을 때, 임시파일인 /tmp/level5.tmp가 존재하지 않을 경우 비밀번호를 기록하고, 파일을 삭제하는 것으로 추측가능함.

#include <stdio.h>

int main()
{
// 변수 선언
char *pass="next password : ";
char *path="/tmp/level5.tmp";

// 임시파일 생성
// 파일 생성 성공 시 파일 디스크립터 반환(0,1,2)
// 파일 생성 실패 시 -1 반환
fd=creat(path,0x180); 

if(fd<0) // 파일 생성 실패 시 (/tmp/level5.tmp가 이미 존재하는 경우)
{
printf("Can not creat a temporary file.\n"); // 구문 출력
remove(path); // 이미 존재하고 있는 /tmp/level5.tmp 삭제
exit(0); // 함수를 종료시킨다
}
else // 파일 생성 성공
{
write(fd,pass,0x1f) // 임시 파일 /tmp/level5.tmp에 pass 내용 쓰기
close(fd); // 파일 닫기
remove(path); // 파일 삭제
}
return 0;
}

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level7 풀이  (0) 2022.10.28
FTZ Level6 풀이  (1) 2022.10.28
FTZ Level4 풀이  (0) 2022.10.27
FTZ Level3 풀이  (0) 2022.10.25
FTZ Level2 풀이  (0) 2022.10.25

+ Recent posts