외로운 Nova의 작업실

정보보안기사 실기 - 1(시스템) 본문

Certification/정보보안기사

정보보안기사 실기 - 1(시스템)

Nova_ 2023. 3. 20. 10:49

- 윈도우 기본 학습

윈도우는 사용자를 LSA서버 서비스를 통하여 인증하고 접근제어를 합니다. 아래는 윈도우 인증 서비스를 그림으로 나타낸 것입니다.

 

<SAM파일 접근 통제 설정>

SAM파일에는 사용자와 그룹 계정의 패스워드 정보가 담겨있는 중요한 파일입니다. 이에따라 적절한 접근 통제가 필요합니다. Administrators 및 System 그룹 외에는 SAM 파일에대한 접근을 제한합니다.

 

<LAN Manager 인증 수준>

Lan Manager은 네트워크를 통한 파일 및 프린터 공유 등과 같은 작업시 인증을 담당하는 서비스입니다. 이때 사용하는 알고리즘중에 NT와 NTLM의 해시함수는 취약하기때문에 NTLMv2 버전의 알고리즘만 사용해야합니다.

 

- UNIX/LINUX 기본 학습

유닉스는 사용자가 계정과 패스워드를 입력하면 /etc/passwd의 계정, 패스워드를 비교합니다. 

 

</etc/passwd 파일>

유닉스는 관리자가 사용자 계정을 만들때마다 해당 사용자와 관련된 정보를 해당 파일에 저장합니다. 아래는 계정정보에대한 필드입니다.

계정명:패스워드:사용자 ID:기본 그룹 ID:기타 정보:홈 디렉터:로그인 쉘

해킹 시 보통 사용자 ID와 기본 그룹 ID를 0으로 변경합니다. 이는 root를 의미하기때문입니다. 따라서 0으로 변경된 계정이 있는지 주기적으로 확인해야합니다.

 

</etc/group 파일>

현재 시스템에 정의되어있는 모든 그룹의 정보를 저장하는 파일입니다. 아래는 필드의 구조입니다.

그룹명:패스워드:그룹 ID:소속된 사용자 계정들

 

<MAC Time>

리눅스의 파일 시스템중 inode list에는 MAC time이 있습니다. MAC time은 파일의 접근에대해서 알 수 있어, 침해 사고가 발생하게되면 무결성 확인 타임라인 분석을 위해 해당 부분을 점검합니다. stat 명령을 통해 확인할 수 있습니다. 첫번부터 마지막 접근시간, 마지막 수정시간, 마지막 교체시간입니다.

 

<하드링크와 심볼릭링크>

하드링크 : inode는 하나의 파일의 identity로 하나의 inode에 여러 파일을 하나의 파일을 링크시키는 것입니다. 하나의 파일을 지워도 다른 하드 링크 파일에 그 내용이 살아 있습니다. 아래 명령어로 생성이 가능합니다.

ln abc.dat dab_hl.dat

심볼릭 링크 : 하나의 파일의 경로를 기반으로 파일에 접근하는 것입니다. 원본이 되는 파일을 지우면 심볼릭 링크는 사용하지못합니다. 아래 명령어로 생성이 가능합니다.

ln -s abc.dat abc_sl.dat

 

<파일 권한 변경>

 

<접근권한 마스크>

 

<퍼미션 검색>

-perm 0644이면 권한이 0644인것만 찾고, -perm -0600이면 권한이 0600이 포함되어있는 것들을 찾습니다.

 

<시간 검색>

-mtime +4 : 수정한지 4일 초과된 파일 찾기

-mtime -4 : 수정한지 4일 미만된 파일 찾기

 

<크기 검색>

-size +3 : 파일 크기가 3 초과한 파일 찾기

-size -3 : 파일 크기가 3미만인 파일 찾기

 

- 유닉스 리눅스 시스템 관리

<ps -ef 실습>

 

<하드디스크 사용량>

du -k : 현재 디렉토리의 파일 크기들을 킬로바이트 형식으로 나타냅니다.(disk usage)

du -s : 현재 디렉토리의 전체 크기를 나타냅니다.

<파일 시스템 용량 정보>

df : 파일 시스템의 전체 공간 및 사용 가능한 공간에 대한 정보를 보여줍니다.(disk free)

<정기적 스케줄러>

형식 : 분 시 일 월 요일 작업

예시 : 20 6 * * 1-5 /work/job parma1(20분 6시 매일 매월 월-금 job을 param1 인수를 가지고 실행)

 

<corntab의 파일제어>

crontab 파일은 사용자 계장별로 만들어집니다. root는 사용자를 명시적으로 지정하여 다른 사용자의 crontab 파일을 편집할 수 있으며 일반 사용자는 자신의 crontab 파일만 편집할 수 있습니다. root가 파일을 편집할때는 아래 명령어를 사용합니다.

crontab -u nova -e : nova의 crontab을 수정합니다.
crontab -u nova -l : nova의 crontab을 출력합니다.
crontab -u nova -r : nova의 crontab을 삭제합니다.

 

<crontab의 명령 접근 제어>

crontab 명령을 실행할 수 있는 사용자를 제한하여 crontab명령을 통한 작업등록을 못하도록 설정합니다. /etc/cron.allow, /ect/cron.deny 파일을 이용합니다. allow파일에 등록되어있는 사용자만이 명령을 실행할 수 있으며 allow 파일먼저 검사합니다.

 

- Unix/Linux 서버 보안

<passwd 파일>

passwd 파일의 필드 구성형식은 아래와 같습니다.

계정:패스워드:유저ID:그룹ID:설명:홈디렉터리:로그인 쉘

로그인 쉘의 경우에는 로그인이 불필요한 계정에대해서 악용되지않도록 쉘을 없애줘야합니다. 웹서버의 경우 로그인이 불필요하기때문에 로그인쉘 경로를 bin/false로 해줍니다.

apache:x:48:48:Apache:/var/www:/bin/false

 

<shadow 파일>

/etc/shadow 경로에 있으며 필드의 구성 형식은 아래와 같습니다.

계정:암호화된 패스워드:최근 변경일:최소 사용기간:최대 사용기간:경고일수:만료이후 비활성일수:만료일

암호화된 패스워드 필드의 구성은 아래와 같습니다.

$1$1ASASDHA$ASJDASONASDF12ASD2ASD
  • $1 : 암호화에 적용된 알고리즘을 표시합니다. 1은 MD5, 2는BlodwFish, 5는SHA-256, 6은SHA-512를 의미합니다.
  • $1ASASDHA : 솔트값을 의미합니다.
  • $ASJDASONASDF12ASD2ASD : 솔트값과 패스워드값을 합친 후 해시값의 결과입니다.

그리고 패스워드 부분에 *이거나 !!이거나 빈값이 들어가는 경우가 있는데 의미는 아래와 같습니다.

  • * : 패스워드가 잠긴상태로 로그인불가하지만 별도의 인증으로 로그인 가능
  • !! : 패스워드가 잠긴상태로 모든 로그인 불가
  • 빈값 : 패스워드가 설정되지 않은 상태

패스워드를 잠그는 명령어는 아래와 같습니다.

passwd -l nova : nova계정을 잠급니다.
passwd -u nova : nova 계정을 풉니다.

또한 패스워드를 저장할때는 shadow파일에 저장하는 방식과 passwd 파일에 저장하는 방식이 있는데 이 방법을 바꾸려면 아래 명령어를 사용합니다.

pwconv : shadow파일에 저장합니다.
pwunconv : passwd 파일에 저장합니다.

 

<root 소유 SUID, SGID 주기적 검사>

SUID, SGID가 설정된 파일들은 취약할 수 있어서 주기적으로 검사해줘야합니다. 검사방법은 find 명령의 -perm 옵션을 사용해서 검사합니다.

find . -user root -perm 4000 : 현재 디렉토리에서 root 소유자의 SUID가 설정된 파일들을 검사합니다.
find . -user root -perm 2000 : 현재 디렉토리에서 root 소유자의 SGID가 설정된 파일들을 검사합니다.

 

<inetd>

inetd는 서버/클라이언트 구조에서 포트개방, 프로그램 등록, 프로그램 호출등을 담당하는 데몬입니다. 연결이 들어오면 inetd 데몬이 먼저 받아서 /etc/inetd.conf 파일을 참조해 적절한 서버에게 연결을 시켜줍니다. TCP Wraaper 서비스와 연동해서 호스트 접근 제어를 할 수 있으며 리눅스 시스템의 경우 xinetd 데몬을 주로 사용합니다. 아래는 inetd.conf 파일의 구조입니다.

서비스명 소켓타입 프로토콜 플래그 사용자계정 실행경로 실행인수

--아래는 예시입니다.
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd -l -a

간단하게 ftp 서비스가 들어오면 root 사용자로 in.ftpd를 실행하라는 설정입니다. 이때 불필요하고 취약한 서비스는 비활성화 해야합니다. 아래는 취약한 서비스들입니다.

  • Simple TCP 서비스 : echo, discard, daytime, chargen
  • r 계열서비스로 인증 없이 관리자의 원격접속을 가능하게 하는 명령어 : rlogin, rsh, rexec
  • 불필요한 rp로 원격 호출 가능 서비스 : rpc.cmsd, rusersd
  • 기타 불필요한 서비스 : finger, tftp, taclk

<TCP wrapper>

TCP wrapper은 allow 파일을 먼저 참조하고 deny 파일을 참조합니다. 이후 호스트 정보가없다면 모든 접근을 허용합니다. 그래서 보통 deny에는 ALL:ALL 설정을 합니다. 아래는 hosts.allow 와 host.deny의 예시입니다.

hosts.deny								hosts.allow
ALL:ALL : twist /bin/echo "연결 거부"	in.telnetd : 192.168.1.1

위 예시는 192.168.1.1 ip는 in.telnetd(텔넷) 서비스를 이용할 수 있게하고 나머지는 차단하도록 설정합니다. 또한 twist 명령어의경우 에는 일종의 경고를 관리자에게 남길 수 있습니다.

 

<PAM>

PAM은 어플리케이션인증모듈로 /lib/security 또는 /usr/bin/security에 있습니다. 프로그램 개발시 별도로 개발하지않고 이 PAM을 이용하면 편리하다는 장점이 있습니다.

PAM의 작동방식은 아래와 같습니다.

pam.d에 어플리케이션을 위한 파일을 만들어줍니다. 예를들어 su 어플리케이션 파일을 만들어줍니다.

그 설정 파일에는 PAM인증 type과 인증 이후 행동, 사용할 인증모듈을 적어줍니다.

아래는 설정 파일의 필드입니다.

pam 모듈 타입		모듈 실행후 PAM 행동결정 		모듈 경로

예를들어 첫번째의 경우 인증(auth)를 진행하고 만약 인증이 성공이면 바로 인증 성공(sufficient)하게하고 인증 모듈은 사용자가 root면 인증을 성공하게하는 모듈(pam_rootok.so)를 쓴다는 뜻입니다.

 

<w 명령어>

w 명령어는 현재 사용자가 어떤 경로로 접속 한 것인지 알 수 있습니다.

root는 tty2로 tty는 서버와 연결된 터미널 포트로 연결됨을 알 수 있습니다. 또한 pts는 가상머티널로 telnet과 같은 원격 터미널로 접속함을 표현합니다.

 

- 시스템 로그 설정과 관리

<utmp 로그파일>

utmp는 현재 로그인한 사용자의 상태정보를 담고있는 로그파일입니다. 보통 바이너리파일로 되어있어서 w, who, finger 등의 명령어를 사용합니다.

 

<wtmp 로그파일>

사용자의 성공한 로그인/로그아웃 정보, 시스템의 Boot/Shutdown 정보에대한 히스토리를 담고 있는 로그파일입니다. 보통 바이너리 파일로 되어있으며 last 명령어를 사용합니다.

 

<lastlog 로그 파일>

가장 최근에 성공한 로그인 기록을 담고 있느 ㄴ로그파일입니다. 보통 바이너리파일로 되어있으며 lastlog, finger 명령을 사용합니다.

-u 옵션은 계정명을 검색할 수 있고 -t 일수 인수로 일수 이내에 접속한 기록을 확인할 수 있습니다.

위 사진은 5일이내 root가 최근 로그인한 로그를 보여줍니다.

 

<btmp, loginlog 로그 파일>

실패한 로그인 시도에대한 기록을 담고 있는 파일입니다. 리눅스는 lastb 명령어를 사용하고 유닉스는 /var/adm/loginlog 파일에서 vi를 통해 로그를 볼 수 있습니다.

 

<sulog 로그 파일>

su 명령을 사용한 결과를 저장한 파일로 Sunos를 포함한 유닉스 계열에서만 볼 수 있습니다. 리눅스는 /var/log/secure 로그 파일에서 볼 수 있습니다. 보통 텍스트 파일로 되어있습니다. 유닉스 계열 로그에서 +는 su 성공 -는 su 실패를 뜻합니다.

 

<acct/pacct 로그 파일>

acct/pacct 로그 파일은 시스템에서 로그인한 모든 사용자가 로그아웃할때까지 입력한 명령어와 터미널 종류, 프로세스 시작 시간 등을 저장한 로그입니다 바이너리 파일로 되어있으며 lastcomm 명령을 사용합니다. 리눅스는 기본 생성 로그파일이 아니므로 "accton /var/account/pacct" 명령 실행이 필요합니다.

F는 fork에 의해 실행, S는 root에의해 실행, X는 시그널에 의해 종료를 표현합니다.

 

<secure 로그 파일>

사용자 생성 삭제 로그인 등의 사용자 인증에대한 정보를 기록하고 있는 로그파일로서 서버보안에 아주 민감하고 중요한 파일입니다. /var/log/secure에 있습니다.

nova가 패스워드 체크에 실패한 이력이 있습니다.

 

<message 로그 파일>

리눅스 시스템의 가장 기본적인 시스템 로그 파일로서 시스템 운영에 대한 전반적인 메시지를 저장하고 있습니다. 주로 데몬들의 실행상황과 내역, 사용자들의 접속 정보, TCP Wrapper 접근 제어 정보 등을 저장합니다. /var/log/messages 파일에 있습니다.

 

- syslog 설정 및 관리

로그 작성 동작 방식을 살펴보면 커널 및 응용 프로그램이 syslog API를 통해 로그를 생성하면 syslogd 데몬 프로세스가 syslog.conf 설정 파일을 참조하여 지정한 로그파일, 콘솔 또는 외부 서버 등에 로그를 기록합니다. 아래는 필드입니다.

facility.priority; facility.priority		action(logfile-location)

facility 서비스에대하여 priority 로그 레벨 이상의 상황이 발생한 경우 action 형식으로 로그를 남기라는 의미입니다. 요새는 syslog보다 rsyslog를 사용합니다.

syslog는 기밀성, 무결성, 가용성 등 정보보호 특성을 고려하지않고 개발되어 UDP 를 통해 로그 전송할때 공격자가  syslog 메시지를 모니터링하여 정보를 알아낼 수 있습니다. 따라서 RFC 3195에서는 BEEP을 이용할 것을 권고합니다. BEEP은 연결지향적이고 재전송을 위한 신뢰성등을 보장합니다.

 

<facility>

* 모든 서비스를 의미합니다.
auth, authoriv 인증 및 보안 관련 메시지입니다.
cron cron 데몬과 atd 데몬에의해 발생되는 메시지입니다.
daemon telnet, ftp 등과 같은 데몬에 의한 메시지입니다.
kern kernel에 의한 메시지로서 커널 메시지입니다.

<priority>

Emergency 시스템이 전면 중단되는 패닉상태입니다.
alert 즉각적인 조치가 필요한 상황입니다.
critical 하드웨어 등의 심각한 오류가 발생한 상황입니다.
Error 일반적인 에러/오류가 발생한 상황입니다.
Warning 경고 메시지입니다.
notice 관리자의 조치가 필요한 상황입니다.
information 의미있는 정보 관련 메시지입니다.
debug 디버깅용 메시지입니다.

<원격 로그 서버 설정 실습>

<syslog 설정 예시>

kern.*							/dev/console : kelnel에 관련된 로그를 콘솔에 출력하는 의미입니다.
*.info;mail.none;cron.none 				/var/log/messages : info 수준이상의로그를 모든 서비스에대해서 messages에  기록하되,mail과cron서비스에대해서는 하지않는다. 
*.emerg							* : 모든 서비스의 emerge 수준이상의 로그를 모든 사용자에게 보내라는 의미입니다.

 

- 리눅스 로그 관리

<로그 모니터링>

secure과 같은 로그를 실시간으로 계속 모니터링하려면 "tail -f /var/log/messages"명령을 이용하면 유용합니다. tail은 마지막 라인을 출력하는 명령어이고 -f 옵션은 실시간으로 출력되는 내용들을 출력해줍니다.

 

<로그파일 순환>

로그파일들을 그대로 방치하면 사이즈가 커지면서 관리하기 어려워지고 시스템 장애가 발생합니다. 따라서 logrotate는 시스템 로그를 관리하기위한 도구로 로그순환, 압축등의 기능을 가지고 있습니다. 아래는 logrotate에대한 관련 파일들입니다.

  • /usr/sbin/logrotate : logrotate 데몬 위치 및 데몬 프로그램
  • /etc/logrotate.conf : logrotate 데몬 설정 파일
  • /etc/logrotate.d : logrotate를 적용할 프로세스 파일
  • /var/lib/logrotate.status : logrotate한 작업내역을 보관한 파일
  • /etc/cron.daily/logrotate : cron에의해 logrotate가 주기적을 실시됨

아래는 logrotate.conf 파일입니다.

weekly : 주 마다 로그파일이 생성되며

rotate 4 : 순환 로그파일은 4개까지 생성됩니다.

create : 순환시 새롭게 로그파일을 생성하며 create root 로 소유자를 지정할 수 있습니다.

dateext : 로그파일의 확장자로 날짜를 붙여서 보관하고

compress : 로그파일을 압축해서 보관합니다.

include /etc/logrotate.d : 해당 디렉터리에 있는 개별 데몬 설정 파일을 포함합니다.

 

- 시스템 해킹

<버퍼오버플로우>

스택 버퍼오버플로우 : 스택에 할당된 버퍼들이 문자열 계싼 등에 의해 정의된 버퍼의 한계치를 넘는 경우 버퍼오버플로우가 발생하여 복귀 주소를 변경하고 공격자가 원하는 임의 코드를 실행합니다.

힙 버퍼 오버플로우 : 힙에 할당된 버퍼들에 문자열 등이 저장되어 질 때 최초 정의된 힙의 메모리 사이즈를 초과하여 문자열등이 저장되는 경우 버퍼 오버플로우가 발생하여 데이터와 함수 주소등을 변경하여 공격자가 원하는 임의 코드를 합니다.

 

<오버플로우방지코드>

입력값 사전 검증을 통해 버퍼오버플로우를 방지할 수 있습니다.

if(stlen(argv[1] >=12{
    if(stlen(argv[1]) >= sizeof(buffer)){
		printf("error!");
		exit(-1);
    }
}

 

<스택 오버 플로우 대응기술>

  • 스택가드 : 메모리상에서 프로그램의 복귀주소와 변수 사이에 특정값(카나리)를 저장해두었다가 그 값이 변경되었을 경우를 오버플로우로 가정하여 프로그램 실행을 중단하는 기술입니다.
  • 스택 쉴드 : 함수 시작시 복귀 주소를 Global LET라는 특수 스택에 저장해두었다가 함수 종료시 저장된값과 스택의 RET를 비교해 다를 경우 오버플로우로 가정하여 프로그램 실행을 중단시키는 기술입니다.
  • ASLR : 메모리 공격을 방어하기위해 주소 공간 배치를 난수화하는 기법입니다.

<레이스 컨디션 공격>

프로세스가 임시파일을 만들떄 그 임시파일을 다른 목적 파일(/etc/shadow)과 연결(심볼릭 링크)하여 악의적인 행위를 하는 것을 말합니다. 아래는 race_cond 파일입니다.

#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

void main(int argc, char **argv){

    FILE *fp;
    if(argc != 3){
        fprintf(stderr, "enter the file name");
        exit(-1);
    }

    sleep(10);

    fp=fopen(argc[1],'w');
    if(fp == NULL){
        fprintf("error!");
        exit(-1);
    }

    fprintf(fp, "%s\n", argv[2]);
    fclose(fp)
    printf("success");
}

위 코드는 파일명과 출력할 데이터를 입력받아, 파일명에 일치하는 파일에 데이터를 출력하는 프로그램입니다. 이때 해당 프로그램이 명시적으로 tmp.dat 파일을 수정한다 했을때, shadow파일을 tmp.dat 파일에 심볼릭 링크 할 수 있습니다.

ln -s /etc/shadow /tmp/tmp.dat

이후 race.cond를 실행시키면,

./race_cond /tmp/tmp.dat root::16118:0:99999:7::

실제 shadow 파일이 변경되게 됩니다.

 

<포맷 스트링 공격>

C언어의 printf()함수등에서 사용되는 문자열의 입출력 형태를 정의하는  문자열의 취약점을 이용한 공격으로 외부로부터 입력된 값을 검증하지않고 입출력 함수의 포맷 스트링을 그대로 사용하는 경우 발생합니다. 아래는 테스트 코드입니다.

int main(int argc, char *argv){
	int age=35;
    char *name = "nova";
    int nbyte = 0;
    
    printf("name:%s, age:%d %n\n", name, age, &nbyte);
    return 0;

위코드는 출력된 문자열의 바이트수를 nbyte변수에 넣는 코드입니다. 출력된 문자열은 "name:nova, age:35"아기때문에 17이 nbyte 변수에 저장됩니다. 이때 nbyte에 오버플로우를 일으켜 ret 주소값을 변조시킬 수 있습니다. 또한 아래와 같은  코드에서는

int main(int agrc, char **argc){
	printf("argv[1]");
    return 0;
    }

argv[1]에 %x를 넣게되면 메모리 내용을 참조할 수 있습니다.

 

Comments