1. 개요

  • 19일 한국인터넷진흥원(KISA)에 따르면 핸디소프트 그룹웨어의 코드서명이 쓰인 악성코드가 유포된 사실을 파악
  • 해당 문제점은 지난 9일 처음 발견됐으며, 이니텍 때와 달리 업데이트 서버가 없다는 점에서 파급력이 크지 않을 것으로 보임
  • 현재까지 확인된 피해 없음

2. 내용

  • 공격방식
    • 이니텍 코드서명 유출과 동일한 공격으로 코드서명 유출
      • 이니텍 코드서명 유출 시 이니텍 전산서버를 해킹한 후 악성프로그램을 설치하고 이후 코드서명을 유출
      • 이니텍의 코드서명을 탑재한 악성프로그램을 만들어 국세청, 국토교통부, 서울시청 등 10개 기관에 유포
    • 탈취한 코드서명을 이용하여 악성코드 배포
    • 악성코드에 감염되면 국내 유명 백신을 무력화한 후 C&C 서버와 통신하며 내부 정보를 유출


[Debian 계열의 리눅스]

◎ 커널 헤더 패키지 설치

 # apt-get install linux-headers

※ linux-headers 는 설치시 정확한 패키지명을 지정하라는 메세지가 발생하는데 "uname -r"을 통해 버전을 확인하고 설치를 하면 됩니다.

 

◎ 개발에 필요한 기본 라이브러리와 헤더파일 등을 가지고 있는 패키지 설치

 # apt-get install build-essential

※ Debian 계열에서 make / compile 과 관련된 에러가 발생하면 build-essential 패키지를 설치해주면 됩니다.

 

◎ Dwarfdump 설치

 # apt-get install dwarfdump

dwartdump 를 설치합니다.

 

[Redhat 계열의 리눅스]

◎ 커널 헤더 패키지 설치

 # yum install kernel-devel

또는

 # rpm --install [패키지명]

 

◎ Libdwarf 설치

 # tar xvfz libdwarf-20170416.tar.gz

 # cd dwarf-20170416/libdwarf

 # ./configure

 # make

 # cd ../dwarfdump

 # ./configure

 # make

 # ln -s (dwarf dir)/dwarfdump/dwarfdump /usr/local/bin/dwarfdump

CentOS 의 경우 Libdwarf 를 자동으로 설치할 수 없기 때문에 소스를 다운로드 받아 수동으로 설치해야 합니다.

다운로드 경로 : https://www.prevanders.net/dwarf.html#releases

 

◎ 개발에 필요한 기본 라이브러리와 헤더파일 등을 가지고 있는 패키지 설치

 # yum install elfutils-libelf-devel

 

◎ 종합 

 # yum groupinstall "Development Tools" -y && yum install kernel-devel kernel-headers glibc* binutils elfutils elfutils-devel elfutils-libelf* gcc subversion

 

[공통]

◎ 볼라틸리티(Volatility) 설치

 # cd volatility

 # python ./setup.py install

다운로드 경로 : http://www.volatilityfoundation.org/26

 

◎ vtypes(kernel's data structures : 커널의 데이터 구조) 생성 

 # cd [volatility directory]/tools/linux

 # make

 # head module.dwarf

make를 진행하면 module.dwarf 파일과 system map file 이 생성됩니다.

 

◎ Symbols 가져오기

 # zip /[volatility directory]/volatility/plugins/overlays/linux/[profile name.zip] volatility/tools/linux/module.dwarf /boot/[make  이후 만들어진 system map file]

리눅스용 프로파일은 커널 데이터 구조와 디버그 심볼로 이루어진 압축 파일 형태로 만들면 됩니다. 이는 Volatility 가 커널 데이터 구조와 디버그 심볼을 통해 필요한 정보를 찾고 해석하기 때문입니다. 심볼은 System.map 파일 안에 있으며 /boot 디렉토리에 있습니다.

리눅스용 프로파일 생성은 make 시 생성된 module.dwarf 파일과 심볼 정보를 가지고 있는 System.map 파일을 zip 파일 형태로 압축하면 됩니다. 

 # zip linux_profile_name.zip module.dwarf /boot/system_map _file.map

만약 dwarf 파일이 생성된 폴더에서 zip 작업을 한다면 생성된 파일을

[volatility directory]/volatility/plugins/overlays/linux 디렉토리에 저장해줍니다.

 

 

◎ 프로파일 확인

 # python ./vol.py --info | grep Profile

volatility 의 info 옵션으로 프로파일이 정상적으로 등록되었는지 확인합니다.

 

[참조 URL]

https://github.com/volatilityfoundation/volatility/wiki/Linux

볼라틸리티(Volatility)를 설치해서 정상적으로 사용하려면 다음 3가지가 선행되어야 합니다.

1. 리눅스 프로파일 생성을 위한 유틸 설치

2. 커널 헤더 패키지 설치

3. 개발에 필요한 기본 라이브러리와 헤더파일 등을 가지고 있는 패키지 설치


해당 내용에 대해서 자세히 알아보겠습니다.

[리눅스 프로파일 생성을 위한 유틸]

볼라틸리티(Volatility)를 설치하면 생각보다 기본 프로파일(Profile) 이 적습니다. 때문에 Profile 을 만드는 작업이 필요하며 profile 을 만드는 유틸을 설치해야합니다.

◎ Libdwarf And Dwarfdump 

원래는 DWARF 2/3/4 Debug 포맷을 가지는 것에서 디버깅 정보를 뽑아내는 유틸인데 여기에서는 리눅스 프로파일 생성에 사용됩니다.


◎ libdwarf 란 무엇입니까?

Libdwarf 는 DWARF2, DWARF3, DWARF4 을 사용하여 응용 프로그램의 읽기(쓰기)를 단순화하기위한 C 라이브러리입니다. SGI 의 컴파일러 작성자 및 디버거 작성자의 업무를 단순화하기 위해 1991년 초 SGI (Silicon Graphics, Inc.)에서 작성되었으며 1990년대 중반에 오픈 소스로 제작되었습니다. SGPL 은 LGPL 버전 2.1에 저작권이 있습니다. ELF 오브젝트 파일에서 DWARF2/3/4 정보를 읽는 용도로 다양한 프로젝트에서 사용됩니다. 또한 컴파일러에서 생성 된 DWARF 정보를 작성할 수 있습니다 (최소한 2개의 시스템 제조업체에서 사용하는 기능). 원래의 AT & T DWARF1 (현재는 그대로) 형식은 DWARF2/3/4 와 완전히 다른 방식으로 구현되어 읽을 수 없습니다.


◎ dwarfdump 란 무엇입니까?

Dwarfdump 는 DWARF 정보를 사람이 읽을 수 있는 형식으로 인쇄하기 위해 libdwarf 를 사용하는 응용 프로그램입니다. 또한 오픈 소스이며 SGI 가 저작권을 보유한 GPL 입니다. libdwarf 를 사용하여 DWARF2/3/4 정보를 읽거나 읽을 수있는 텍스트 출력을 제공하는 예제를 제공합니다.


◎ DWARF 란 무엇입니까?

널리 사용되는 표준화된 디버깅 자료 형식입니다. DWARF 는 원래 ELF 파일 형식을 위해 만들어 졌지만, 이것은 목적 파일과 독립적입니다. 이름은 중세 판타지인 "ELF" 같은 것으로서 공식적인 뜻은 없지만 이후에 배크로님(backronym-이미 존재하는 단어에 맞추기 위해 만들어진 약어)인 'Debugging With Attributed Record Formats' 이 제안되었습니다.

DWARF 의 첫 버전은 지나친 저장 공간을 사용하였지만 호환 불가능한 다음 버전인 DWARF-2 는 자료 크기를 줄이기 위해 다양한 인코딩 기법들을 추가하였습니다. DWARF 는 즉시 범용적으로 받아들여지지 않았습니다. 예를 들면 썬 마이크로시스템즈나 리눅스에서 DWARF-2는 1990년대 후반까지도 일반적으로 채택되지 않았습니다.


자유 표준 그룹(Free Standards Group)의 DWARF 워크그룹은 2006년 1월에 DWARF 버전 3을 릴리즈하였습니다. 이것은 C++ 이름공간과 추가적인 컴파일러 최적화 기법들의 지원을 추가하였습니다. DWARF 위원회는 2010년 버전 4를 공개하였으며 개선된 데이터 압축, 최적화된 코드에 대한 더 나은 명세 그리고 C++ 언어의 새로운 특징들을 지원합니다. 


[커널 헤더 패키지]

debian 계열에서는 linux-headers 커널 헤더 패키지를 설치해야하고

redhat 계열에서는 kernel-headers 커널 헤더 패키지를 설치해야합니다.


[개발에 필요한 기본 라이브러리와 헤더파일 등을 가지고 있는 패키지]

debian 계열에서는 build-essential 패키지를 설치해야하고

redhat 계열에서는 elfutils-libelf-devel 패키지를 설치해야합니다.

<순서>

[Redhat 계열의 리눅스]

◎ 업그레이드 순서

◎ 커널업데이트 없이 업그레이드

◎ 특정버전 커널업그레이드(자동)

◎ 특정버전 커널업그레이드(수동)

◎ 구커널이미지 삭제



<내용>

[Redhat 계열의 리눅스]

OS종류 : RHEL, CentOS, Fedora, SUSE 등

패키지 설치, 업데이트, 삭제 명령어 : rpm(Redhat Package Manager), yum(Yellowdog Updater Modified)


◎ 업그레이드 순서

1. 패키지 정보 업데이트

 # yum -y update

각 업데이트 저장소에서 업데이트 패키지 목록을 갱신합니다.


2. 패키지 업그레이드

 # yum upgrade

패키지 목록과 보유한 목록을 비교하여 실제 패키지 업데이트를 수행합니다.


◎ 커널업데이트 없이 업그레이드

1. 커널업데이트 금지 설정

 # yum update --exclude=kernel*

커널업데이트를 제외합니다. 또는 /etc/yum.conf에서 다음 문장을 추가해줍니다. exclude=kernel*


2. 패키지 업그레이드

 # yum upgrade

패키지 목록과 보유한 목록을 비교하여 실제 패키지 업데이트를 수행합니다.


◎ 특정버전 커널업그레이드(자동)

1. 커널 정보 확인

 # uname -r

또는

 # cat /proc/version 

현재 부팅되어있는 커널 정보를 확인합니다.


2. 리눅스 커널 이미지 버전 검색

 http://vault.centos.org/

http://vault.centos.org/ 에서 리눅스 커널 이미지 버전을 검색합니다


3. 패키지 저장소(Repository) URL 수정

 # cd /etc/yum.repos.d

 # cp CentOS-Base.repo CentOS-Base.repo.bak

 # vi CentOS-Base.repo

 [base]

 baseurl=http://vault.centos.org/버전/os/x86_64/

 gpgkey=http://vault.centos.org/버전/os/x86_64/RPM-GPG-KEY-CentOS-버전

 [updates]

 baseurl=http://vault.centos.org/버전/updates/x86_64/

 gpgkey=http://vault.centos.org/버전/os/x86_64/RPM-GPG-KEY-CentOS-버전

 [extras]

 baseurl=http://vault.centos.org/버전/extras/x86_64/

 gpgkey=http://vault.centos.org/버전/os/x86_64/RPM-GPG-KEY-CentOS-버전

 [centosplus]

 baseurl=http://vault.centos.org/버전/centosplus/x86_64/

 gpgkey=http://vault.centos.org/버전/os/x86_64/RPM-GPG-KEY-CentOS-버전

 [contrib]

 baseurl=http://vault.centos.org/버전/contrib/x86_64/

 gpgkey=http://vault.centos.org/버전/os/x86_64/RPM-GPG-KEY-CentOS-버전

편집을 통해 mirrorlist 대신 baseurl 을 위 내용으로 추가하여 대신하고 gpgkey를 수정합니다.


4. 패키지 정보 업데이트

 # yum -y update

각 업데이트 저장소에서 업데이트 패키지 목록을 갱신합니다.


5. 패키지 업그레이드

 # yum upgrade

패키지 목록과 보유한 목록을 비교하여 실제 패키지 업데이트를 수행합니다.


6. 재부팅

 # reboot


◎ 특정버전 커널업그레이드(수동)

1. 커널 다운로드

 http://www.kernel.org

또는

 # wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-버전.tar.zx

또는

 # wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-버전.tar.gz

www.kernel.org 에서 원하는 커널버전의 tar.xz 를 다운로드 받습니다.

또는 링크주소를 복사하여 wget으로 tar.xz 이나 tar.gz 를 다운로드 받습니다.


2. 다운로드 파일 이동

 # mv linux-버전.tar.zx /usr/src

또는

 # mv linux-버전.tar.gz /usr/src

다운로드 받은 파일을 /usr/src 로 이동합니다.


3. 압축해제

 # xz -d linux-버전.tar.zx

 # tar -xvf linux-버전.tar

tar 와 xz 포맷으로 압축된 파일의 압축을 해제합니다.

또는

 # tar -xvzf linux-버전.tar.gz

tar.gz 포맷으로 압축된 파일의 압축을 해제합니다.


4. 심볼릭링크

 # ln -s /usr/src/linux-버전 /usr/src/linux


5. 환경설정

 # cd /usr/src/linux

 # make mrproper

 # make clean

make mrproper : 기존에 설정되어 있던 모든 의존관계 및 환경 설정  값들을 제거 합니다

make clean : 기존 소스 컴파일 작업으로 생성된 파일들 삭제합니다.


6. 컴파일할 소스파일 복사

 # cp /boot/config-`uname-r` ./.config

현재 사용하고 있는 커널 설정 파일을 복사합니다.


7. 커널환경설정

 # make menuconfig

Load 메뉴를눌러 .config 소스 파일을 불러옵니다. 소스파일 로딩이 완료되면 General setup 항목을 <Enter> 를 이용해 선택합니다.

Enable deprecated sysfs features to support old userspace too 라는 항목을 <Space bar> 를 이용해 체크하고 저장합니다.


::추가사항::

화면이 깨진다면 # yum install gcc* ncurses-devel 을 실행 후 진행하시기 바랍니다.

gcc : 컴파일에 필요한 gcc 컴파일러 설치

ncurses-devel : 텍스트 기반 화면처리 라이브러리


8. 커널 컴파일

 # make all

커널 설정 파일 .config를 사용하여  커널 소스를 컴파일 합니다


9. 커널 설치

 # make modules_install

 # make install

컴파일된 모듈들을 설치합니다.


10. 커널 적용을 위한 default 부팅 값 수정

 # vi /boot/grub/grub.conf

새로 설치한 커널이 첫번째 라인에 있으므로 default=0 으로 설정합니다.


◎ 구커널이미지 삭제

리눅스는 커널 업데이트가 빈번합니다. 그리고 매번 업그레이드할 때마다, 이전의 커널 이미지는 삭제되지 않고 남아 있습니다. 때문에 커널 이미지를 삭제해주는 작업이 필요합니다.

1. 커널 정보 확인

 # uname -r

또는

 # cat /proc/version 

현재 부팅되어있는 커널 정보를 확인합니다.


2. 커널 리스트 확인

 # rpm -q kernel

현재 설치되어있는 커널 리스트를 확인합니다.


3.1. 커널 이미지 삭제

 # yum erase kernel-버전

불필요한 커널을 삭제합니다.


종합

 # yum install yum-utils

 # package-cleanup --oldkernels --count=1

yum-list를 이용해서 위의 1~3 단계를 한번에 실행합니다. count 는 구버전의 커널을 몇개까지 남겨 놓을지 설정하는 옵션입니다. 기본 값은 5입니다.



<순서>

[Debian 계열의 리눅스]

◎ 업그레이드 순서

◎ 커널업데이트 없이 업그레이드

◎ 특정버전 커널업그레이드(자동)

◎ 특정버전 커널업그레이드(수동)

◎ 구커널이미지 삭제



<내용>

[Debian 계열의 리눅스]

OS종류 : Debian, Ubuntu, Kali 등

패키지 설치, 업데이트, 삭제 명령어 : dpkg(package manager for Debian), apt-get(Advanced Packaging Tool package handling utility)


업그레이드 순서

1. 패키지 정보 업데이트

 # apt-get update

실제 패키지를 설치하지 않고 신규버전 패키지의 정보를 다운받아 이용 가능한 패키지의 정보를 /etc/apt/sources.list 파일에 업데이트 패키지 목록을 갱신하며 update 는 항상 upgrade 전에 실행되어야 합니다.


2.1. 패키지 업그레이드

 # apt-get upgrade -y

update 로부터 패키지 목록과 보유한 목록을 비교하여 장비내에 존재하는 실제 패키지 업그레이드를 수행합니다.

가장최신버전으로 설치하기 위해 사용되며 설치된 패키지가 제거되거나 설치되어 있지 않은 패키지가 설치되는 작업은 하지 않습니다.

-y : 프롬프트에 자동으로 yes라는 메시지가 표시됩니다. 모든 프롬프트에 대한 응답을 "예"라고 가정하고 비대화식으로 실행합니다.


2.2. 패키지 업그레이드 및 추가 패키지 설치

 # apt-get dist-upgrade

의존성 검사를 수행하면서 새로운 버전으로 업그레이드를 수행합니다.

컴퓨터에 설치된 꾸러미는 아니지만 사용에 필요한 추가 꾸러미를 설치하는 작업도 수행하기 때문에 이미 설치된 꾸러미를 최신 판으로 바꿔주는 upgrade 와는 차이가 있습니다.


◎ 커널업데이트 없이 업그레이드

1. 커널업데이트 금지 설정

 # apt-mark hold linux-image-generic linux-headers-generic

커널업데이트를 금지합니다.


2. 패키지 정보 업데이트

 # apt-get update


3. 패키지 업그레이드

 # apt-get upgrade -y


종합

 # apt-mark hold linux-image-generic linux-headers-generic && apt-get update && sleep 1 && apt-get upgrade -y

위의 1~3 단계를 한번에 실행합니다.


특정버전 커널업그레이드(자동)

1. 커널 정보 확인

 # uname -r

또는

 # cat /proc/version 

현재 부팅되어있는 커널 정보를 확인합니다.


2. 패키지 정보 업데이트

 # apt-get update


3. 리눅스 커널 이미지 버전 검색

 # apt-cache search linux-image

패키지 관리자의 리스트에서 리눅스 커널 이미지 버전을 검색합니다


4. 리눅스 커널 이미지 설치

 # apt-get install linux-image-버전

검색한 여러 버전중 가장 최신 버전을 위 명령어를 통해 입력하면 해당 커널 버전에 관련된 커널 패키지가 같이 설치됩니다.


5. 재부팅

 # reboot


◎ 특정버전 커널업그레이드(수동)

1. 커널 정보 확인

 # uname -r

또는

 # cat /proc/version 

현재 부팅되어있는 커널 정보를 확인합니다.


2. 패키지 다운로드

 # wget http://kernel.ubuntu.com/~kernel-ppa/mainline/해당내용

먼저 http://kernel.ubuntu.com/~kernel-ppa/mainline 에 접속해서 확인 후 필요 버전을 다운로드 합니다.


3. 패키지 설치

 # dpkg -i linux-headers-버전*.deb linux-image-버전*.deb

또는

 # dpkg -i *.deb 


4. grub2 업데이트

 # update-grub2

커널 이미지 정보가 반영되도록 grub2를 업데이트합니다.


5. 재부팅

 # reboot 


구커널이미지 삭제

리눅스는 커널 업데이트가 빈번합니다. 그리고 매번 업그레이드할 때마다, 이전의 커널 이미지는 삭제되지 않고 남아 있습니다. 때문에 커널 이미지를 삭제해주는 작업이 필요합니다.


1. 커널 정보 확인

 # uname -r

또는

 # cat /proc/version 

현재 부팅되어있는 커널 정보를 확인합니다.


2. 커널 리스트 확인

 # dpkg --list | grep linux-image

현재 설치되어있는 커널 리스트를 확인합니다.


3.1. 커널 이미지 삭제

 # apt-get remove linux-image-버전-generic

불필요한 커널 이미지를 삭제합니다.


3.2. 커널 이미지 삭제(설정파일 포함)

 # apt-get --purge remove linux-image-버전-generic

불필요한 커널 이미지와 함께 설정파일까지 모두 삭제합니다.


종합

 # purge-old-kernels --keep 1

purge-old-kernels 를 이용해서 위의 1~3 단계를 한번에 실행합니다. keep 는 구버전의 커널을 몇개까지 남겨 놓을지 설정하는 옵션입니다. 기본 값은 2입니다.


4. grub2 업데이트

 # update-grub2

삭제된 커널 이미지 정보가 반영되도록 grub2를 업데이트합니다.


5. 재부팅

 # reboot 


볼라틸리티(Volatility)는 최초 2006년 컴퓨터 공학자이자 기업가인 아론 월터스(Aaron Walters)에 의해 메모리 포렌식(memory forensics)관련 FATKit 프로젝트에서 출발하여 볼라툴즈 프로젝트(Volatools Project)로 발전했습니다.

그 이후 2007년 아론 월터스에 의해 볼라틸리티 프레임워크(Volatility Framework)개발팀인 볼라틸 시스템즈(http://volatilesystems.blogspot.kr/)가 만들어지고 현재는 아론 월터스가 회장으로 있는 볼러틸리티 재단(Volatility Foundation)의 사고조사 및 멀웨어 분석을 위한 오픈소스(OpenSource) 소프트웨어로 자리잡았습니다.

플러그인(Plugin)을 자신이 직접 만들어 사용이 가능한 이유로 메모리 분석과 관련된 다양한 기능을 가진 공개용 Plugin 파일이 개발되고 있습니다.

또한 침투 테스트(Pentest)를 목적으로 개발된 데비안 기반 운영체제인 칼리 리눅스(Kali Linux, http://www.kali.org/downloads)에도 포함되어 있습니다.

Volatility 는 파이썬(Python) 프로그래밍 언어로 작성되었고 Microsoft Windows, MacOSX 및 Linux 를 지원합니다.(버전 2.6기준)


[지원 포맷 형식]

Volatility 는 다양한 파일 포맷 형식을 지원하고 이러한 포맷 형식 간에 전환이 가능합니다.

  - Raw linear sample (dd)

  - Hibernation file (from Windows 7 and earlier)

  - Crash dump file

  - VirtualBox ELF64 core dump

  - VMware saved state and snapshot files

  - EWF format (E01) 

  - LiME format

  - Mach-O file format

  - QEMU virtual machine dumps

  - Firewire 

  - HPAK (FDPro)


[요구사항]

Python 2.6 또는 이후 버전(3.0 불가).

Web:

http://www.python.org


[관련 홈페이지]

For information or requests, contact:

Volatility Foundation


Web:

http://www.volatilityfoundation.org

http://volatility-labs.blogspot.com

http://volatility.tumblr.com

https://github.com/volatilityfoundation/volatility

VMware 주요 확장자에 대한 설명

.log – 가상 머신(Virtual Machine)에 대한 일반적인 활동 기록 파일

.vmdk – 게스트 운영체제(Guest OS)에 대한 실질적인 가상 하드 드라이브(Virtual Hard Drive)

.vmem – 게스트 운영체제에 대한 실질적인 가상 페이징 파일(Virtual Paging File)

.vmsn – VMware에서 생성하는 스냅샷(Snapshot) 파일로, 게스트 운영체제에 대한 상태 저장

.vmsd – VMware에서 생성한 스냅샷 파일에 대한 메타데이터(Metadata) 기록 파일

.nvram – 게스트 운영체제에 대한 바이오스(BIOS) 정보 기록 파일

.vmx – 게스트 운영체제에 대한 설정 기록 파일

.vmss – 게스트 운영체제를 일시 중지(Suspend) 상태로 변경할 경우, 당시의 게스트 운영체제 상태를 저장한 파일

 

VMware 가 가지고 있는 위와 같은 주요 확장자 파일들 중 메모리 덤프 파일은 .vmem 확장자를 가진 파일입니다. VMware 이미지에서 .vmem 확장자 파일을 추출하기 위해서는 현재 메모리 상태를 저장해야 됩니다. 실행 중인 이미지를 일시 중지(Suspend) 시키면 .vmem 파일이 생성되는데 해당 폴더에서 .vmem 파일을 복사하면 됩니다.

VMware 이미지는 메모리덤프를 위해 별도의 유틸리티가 필요 없네요.

ELF statifier 는 동적 링크된 실행 파일과 공유 라이브러리를 하나의 파일로 합치기 위한 툴로 동적 실행 파일에서 정적 실행 파일을 생성합니다. 침해사고 시스템을 분석할 때는 라이브러리에 의존하지 않기 위해 정적 실행 파일을 사용해야 하지만 정적 컴파일 된 파일은 사이즈가 크다는 단점이 존재합니다.

 

동적으로 링크 된 공유 라이브러리는 정적으로 링크 된 공유 라이브러리보다 디스크 공간을 효율적으로 사용하며, 보다 효율적인 방식으로 보안 업데이트를 수행 할 수 있습니다. 그리고 동적 라이브러리의 특정 버전으로 컴파일 된 실행 파일은 해당 버전의 공유 라이브러리가 실행중인 시스템에서만 사용이 가능합니다.

 

Fedora 9 와 openSUSE 11 를 각각 실행해 보면 일부 공유 라이브러리의 버전이 다른 것을 볼 수 있으며 이러한 버전 차이로 인해 컴퓨터간에 실행 파일을 복사하더라도 파일을 실행할 수 없습니다. 하지만 ELF Statifier 를 이용하면 동적 라이브러리를 찾는 실행 파일 대신에 공유 라이브러리를 포함한 정적으로 링크 된 실행 파일을 만들 수 있으며 Fedora 컴퓨터에서 컴파일 한 실행 파일을 다시 컴파일하지 않고도 openSUSE 시스템에서 실행할 수 있습니다. 물론 실행 파일을 복사하는 시스템과 실행 파일을 복사하려는 시스템은 동일한 아키텍처를 가져야합니다.

 

물론 이렇게하려면 정적 실행 파일에 필요한 공유 라이브러리 복사본이 포함되어 있기 때문에 일부 디스크 공간을 희생해야하지만 요즘에는 디스크 공간이 크기 때문에 중요하지 않습니다. 실행 파일이 libfoo 라는 공유 라이브러리에 동적으로 링크되어 있고 libfoo 에 대한 보안 업데이트가 있는 경우 어떻게 될지 고려해 보십시오. 응용 프로그램이 동적으로 링크되어 있다면 libfoo 의 공유 사본을 업데이트 할 수 있으며 응용 프로그램은 더 이상 이전 libfoo 의 보안 문제로 취약하지 않습니다. 반면에 정적으로 링크 된 실행 파일의 경우 이전 libfoo 라는 공유 라이브러리 복사본이 포함되어 있기 때문에 최신 libfoo 및 보안 업데이트를 적용하려면 정적으로 링크 된 실행 파일을 다시 만들어야 합니다.

 

[Statifier 설치]

ELF Statifier 는 openSUSE 10.3 에서는 1-Click 으로 설치되지만 Ubuntu 나 Fedora 에서는 1-Click 으로 설치되지 않습니다. 여기서는 ELF Statifier 1.6.14 버전을 사용했으며 ELF Statifier 는 자동 도구를 사용하지 않으므로 간단하게 호출하여 컴파일 할 수 있습니다. make 컴파일과 설치는 아래와 같습니다.

 

 # tar xzvf statifier-1.6.14.tar.gz 
 # cd ./statifier-* 
 # make 
 # make install

 

[ASLR 해제]

정적 실행 파일을 만들기 전 메모리상의 공격을 방어하기 위해 주소 공간배치를 난수화 시키는 기법(ASLR : Address Space Layout Randomization) 은 비활성화해야 합니다. 주소 공간배치를 난수화하면 실행 파일을 실행할 때마다 libc 함수의 위치가 항상 바뀌기 때문에 return-to-libc 공격과 같은 BOF 공격으로부터 메모리를 보호하게 됩니다. 하지만 정상적인 정적 실행 파일 또한 실행이 불가합니다.

([Linux] 메모리 보호 기법[Linux] 메모리 보호 기법 중 ASLR와 NX 설정값 확인 및 변경글을 참고해주세요.)

 

아래와 같이 randomize_va_space 매개 변수를 변경하여 보안을 해제합니다. randomize_va_space 변경은 실행 파일 자체에 대한 공격뿐만 아니라 버퍼 오버 플로우에 의존하여 시스템을 손상시키는 공격 시도에도 영향을 미칩니다. 주소 공간배치 난수화가 없으면 두 공격에 더 취약 해집니다.

아래와 같이 randomize_va_space를 0으로 설정하고 정적 실행 파일을 만들면 됩니다.

 # cd /proc/sys/kernel
 # cat randomize_va_space 
 2 
 # echo 0 > randomize_va_space 
 # cat randomize_va_space 
 0

 

[정적 실행 파일 생성]

다음으로 statifier 유틸리티를 사용하는 방법의 예로서, ls 명령에 대한 정적 실행 파일을 생성해보겠습니다.

먼저 동적으로 링크 된 실행 파일의 복사본을 만들고 동적으로 링크 된 파일을 검사합니다.

statifier 는 동적으로 링크 된 실행 파일의 경로를 첫 번째 인수로 사용하고 정적으로 링크 된 실행 파일을 두 번째 인수로 만들려는 경로로 실행합니다.

ldd 명령은 ls-static 이 동적으로 링크 된 라이브러리를 필요로하지 않다고 보여주고 있습니다.

다음 명령은 정적 실행 파일 ls 에서 바이너리 크기가 크게 증가한 것을 보여줍니다.

 

 # mkdir test
 # cd ./test 
 # cp -a /bin/ls ls-dynamic 
 # ls -lh 
 -rwxr-xr-x 1 root root 112K 2008-08-01 04:05 ls-dynamic 
 # ldd ls-dynamic 
 linux -gate.so.1 => (0x00110000) 
 librt.so.1 => /lib/librt.so.1 (0x00a3a000) 
 libselinux.so.1 => /lib/libselinux.so.1 (0x00a06000) 
 libacl.so .1 => /lib/libacl.so.1 (0x00d8a000) 
 libc.so.6 => /lib/libc.so.6 (0x0084e000) 
 libpthread.so.0 => /lib/libpthread.so.0 (0x009eb000 ) 
 /lib/ld-linux.so.2 (0x0082e000) 
 libdl.so.2 => /lib/libdl.so.2 (0x009e4000) 
 libattr.so.1 => /lib/libattr.so.1 (0x0606d000)
 # statifier ls-dynamic ls-static 
 # ldd ls-static 
 not a dynamic executable
 # ls -lh ls-static 
 -rwxr-x --- 1 root root 2.0M 2008-10-03 12:05 ls-static
 # ls-static / tmp 
 ... 

 

[문제해결1]

 # ls-static -lh 
 Segmentation fault

statified 실행 파일을 실행할 때 세그먼테이션 오류가 발생하면 스택 무작위화를 비활성화하고 statified 실행 파일을 다시 작성해야 합니다. 또한 정적 컴파일된 파일을 복사 후 실행하려면 ASLR 기능을 사용하지 않아야 합니다.

 

[문제해결2]

 조건  A-PC CentOS 실행 A-PC Ubuntu 실행 B-PC CentOS 실행 B-PC Ubuntu 실행
 A-PC CentOS에서
컴파일
 O   O   X  X
 B-PC CentOS에서
컴파일
 O  O  O  O

PC가 달라지면 실행이 안되는 경우도 발생 할 수 있으니 충분히 테스트해보시기 바랍니다.

 

[참고사이트]

원문 : https://www.linux.com/news/quickly-move-executable-between-systems-elf-statifier

ELF statifier 설명 : http://statifier.sourceforge.net/

ELF statifier 다운로드 : https://sourceforge.net/projects/statifier/

1. ASLR(Address Space Layout Randomization) 설정 값 확인 및 변경

ASLR(Address Space Layout Randomization) 설정 값을 확인합니다.

 # cat /proc/sys/kernel/randomize_va_space

 

randomize_va_space=0 //ASLR 해제

randomize_va_space=1 //랜덤 스택 & 라이브러리 활성화

randomize_va_space=2 //랜덤 스택 & 라이브러리 & 힙 활성화

 

ASLR(Address Space Layout Randomization) 설정 값을 변경합니다. 임시로 변경하는 방법이기 때문에 재부팅되면 설정 값이 기본 값(2)으로 변경됩니다.

 # echo 0 > /proc/sys/kernel/randomize_va_space
 # echo 1 > /proc/sys/kernel/randomize_va_space
 # echo 2 > /proc/sys/kernel/randomize_va_space

 

2. DEP / NX(Not Excutable) 설정 값 확인 및 변경

DEP / NX(Not Excutable) 설정 값을 확인합니다. 

 # cat /proc/sys/kernel/exec-shield

 

exec-shield=0 // ExecShield 보호 비활성화

exec-shield=1 // ExecShield 보호 활성화

 

DEP / NX(Not Excutable) 설정 값을 변경합니다. 임시로 변경하는 방법이기 때문에 재부팅되면 설정 값이 기본 값(1)으로 변경됩니다.

# echo 0 > /proc/sys/kernel/exec-shield
 # echo 1 > /proc/sys/kernel/exec-shield

 

3. sysctl 명령을 이용한 설정값 확인 및 변경

sysctl 명령은 커널 변수의 값을 제어하여 시스템을 최적화 할 수 있는 명령으로 시스템의 /proc/sys 디렉토리 밑에 있는 매개변수를 제어합니다. echo 명령을 사용하거나 sysctl 명령을 이용하여 /proc 디렉토리 밑에 있는 항목을 직접 편집하거나 설정할 수 있습니다.

 

sysctl 옵션
 -a : 현재 커널 매개변수와 값을 보여줍니다
 -p : sysctl 환경변수파일(기본값은 /etc/sysctl.conf)의 설정상태를 보여줍니다
 -n : 특정키에 대한 값을 보여줍니다.
 -w variable=value : 변수에 값을 설정합니다.
 -A : 테이블형재로 설정가능한 파라미터를 보여줍니다. -a 와 같습니다.

 

sysctl 명령을 이용하여 ASLR(Address Space Layout Randomization) 설정 값과 DEP / NX(Not Excutable) 설정 값을 확인합니다.

# sysctl -a | grep -E "exec-|randomi"
 kernel.exec-shield=1
 kernel.randomize_va_space=2

 

sysctl 명령을 이용하여 ASLR(Address Space Layout Randomization) 설정 값을 변경합니다. 임시로 변경하는 방법이기 때문에 재부팅되면 설정 값이 기본 값(2)으로 변경됩니다.

# sysctl -w kernel.randomize_va_space=0
 # sysctl -w kernel.randomize_va_space=1
 # sysctl -w kernel.randomize_va_space=2

 

sysctl 명령을 이용하여 DEP / NX(Not Excutable) 설정 값을 변경합니다. 임시로 변경하는 방법이기 때문에 재부팅되면 설정 값이 기본 값(1)으로 변경됩니다.

# sysctl -w kernel.exec-shield=0
 # sysctl -w kernel.exec-shield=1

 

시스템을 시작할 때부터 ASLR(Address Space Layout Randomization) 설정과 DEP / NX(Not Excutable) 설정 해제를 자동으로 설정하는 방법

/etc/sysctl.conf 파일 안에 아래 내용을 추가한 후 재부팅을 합니다.

# vi /etc/sysctl.conf
 kernel.randomize_va_space=0
 kernel.exec-shield=0

 

다른 메모리 보호 기법은 [Linux] 메모리 보호 기법을 참고해주세요.

[리눅스 메모리 보호 기법]

1. ASLR(Address Space Layout Randomization)

2. DEP / NX(Not Excutable)

3. ASCII-Armor

4. Stack canary

 

예제)

 # cat /proc/self/maps

스택, 힙, 라이브러리 등의 주소가 랜덤하게 바뀌는지 확인이 가능합니다.

 

1. ASLR(Address Space Layout Randomization)

 

메모리상의 공격을 방어하기 위해 주소 공간배치를 난수화 시키는 기법입니다. 스택, 힙, 라이브러리 등의 데이터 영역 주소등을 난수화 시킨 주소로 프로세스의 주소 공간에 배치하는 것입니다. 리눅스 커널 2.6.12 이후로 적용 되었습니다.

(상세한 내용은 [Linux] 메모리 보호 기법 중 ASLR와 NX 설정값 확인 및 변경을 참고해주세요)

 

2. DEP / NX(Not Excutable)

 

메모리상의 보호를 위해 stack 과 heap 에서 코드가 실행되는 것을 막는 기법입니다. 공격자가 BOF 공격을 일으키면 DEP 가 적용된 상태에서는 실행권한이 없으므로 프로그램에 대한 예외처리 후 종료가 됩니다.

 

3. ASCII-Armor

 

Libc 영역을 보호하기 위한 기법으로 상위주소를 \x00 으로 시작하게 만들어 공격자가 라이브러리를 호출하는 BOF 공격을 하여도 NULL 바이트가 삽입된 주소로 접근 할 수 없게 됩니다.

 

4. Stack canary

 

RET
SFP
BUFFER

 

위 처럼 되있는 메모리 구조가

 

RET
SFP
CANARY
BUFFER

 

이렇게 SFP와 BUFFER 데이터 사이에 CANARY 가 추가되어 스택의 BOF를 모니터링하는 역할을 담당합니다. BOF 가 발생하면 CANARY 데이터값의 변조로 오버플로우에 대한 경고를 하고 프로그램을 종료시킵니다. 

 

CANARY 데이터는 다음과 같이 구성되어 있습니다.

 

 1) Terminator canaries
 문자열 끝문자를 이용하여 canary 를 구성하는 방법으로 canary 값으로 NULL, CR, LF, Oxff 값의 조합이 사용됩니다. 공격자는 공격시,  종료문자로 구성된 canary 값에 접근을 할 수 없게됩니다.


 2) Random canary
 프로그램을 실행할 때마다 임의의 canary 값을 삽입을 합니다. 이에 따라 공격자는 Canary 값을 예측불가능하므로 공격에 어려움이  발생합니다.


 3) Null canary(0x00000000)
 메모리상의 공격을 막기위해 canary 값을 NULL 로 구성합니다. 공격자는 공격코드상에 NULL 값을 삽입할 수 없으므로 canary 값에  접근이 불가능합니다.

 

[참고 사이트]

https://bpsecblog.wordpress.com/2016/05/16/memory_protect_linux_1/

http://dokydoky.tistory.com/449

http://blog.naver.com/revsic/220531540037

+ Recent posts