1. 시스템에 동작중인 전체 프로세스를 보는 명령어
#ps aux
#ps -ef
2. 프로세스에게 신호(signal)을 보낼 때 쓰는 명령어
#kill
3. kill 의 전체 신호 목록을 보는 옵션
#kill -l
4. 프로세스를 종료하는 신호
#kill -15 // 막을 수 있다.
#kill -9 // 못막는다. 이 신호를 받으면 무조건 종료.(권한이 있을 때)
// 권한이 낮은 사용자가 권한이 높은 사용자의 프로세스를 종료하려 할 때(-9를 이용) 종료 불가.
// 9번 신호는 최소한 동등한 권한이거나 높은 권한이어야 종료할 수 있다.
5. 자식 프로세스를 생성하는 함수
#fork()
6. 프로세스에서 명령어를 대체하는 함수
exec() 계열의 함수 -> #man exec
7. ls /proc 했을 때 나오는 번호(디렉토리)는 무엇인가?(파란색)
/proc 디렉토리에서 번호로 된 디렉토리는 하나의 프로세스에 해당한다.
-> 현재 시스템에서 동작중인 프로세스를 의미하고 #ps aux | head 를 이용해서 나오는 번호와 일치된다.
========================================================================= PROC-LAB> 프로그램을 짤때 15번 신호(signal)을 무시하는 방법
!!! trap 을 이용한다 !!!
- 리눅스에서 실행파일 형식
1. 바이너리 파일
- 바이너리 파일에서 signal 함수를 사용해서 시그널을 무시한다.
2. 쉘 스크립트
- 쉘 스크립트 파일에서 trap 명령어를 이용해서 시그널을 무시한다.
- 쉘스크립트를 이용한 SIGINT 시그널을 무시하기
#install /dev/null test1.sh
#install /dev/null test2.sh
- trap 명령어를 이용해서 SIGTERM(15) 신호를 무시하는 코드를 넣는다.
!!! trap 형식 : trap "명령어" 시그널번호 !!!
!!! 일반적으로 SIGTERM 시그널이 오면 trap "" SIGTERM 을 사용한다 !!!
# install /dev/null test.sh
# vi test.sh
-- test.sh --
#!/bin/sh
trap "echo ^^*" SIGTERM
while :
do
sleep 1
done
-- test.sh --
# ./test.sh &
[1] 12357
# kill 12357
^^*
# jobs
[1]+ Running ./test.sh &
#kill 12357
# ^^*
# jobs
[1]+ Running ./test.sh & =========================================================================
========================================================================= PROC-LAB(?)> SIGKILL 의 signal 이 막힐까 ? !!! -9 (강제종료) or SIGKILL 은 막을 수 없다 !!! # install /dev/null test2.sh # vi test2.sh -- test2.sh -- #!/bin/sh trap "echo ^^*" SIGTERM trap "echo :)" SIGKILL while : do printf . sleep 1 done -- test2.sh -- # ./test2.sh & [1] 11874 # kill 11874 ^^* ... # kill -9 11874 # [1]+ Killed ./test2.sh
=========================================================================
2. C 언어를 이용한 SIGINT 시그널을 무시하기 # vi test3.c -- test3.c -- #include <stdio.h> // printf, fflush #include <unistd.h> // sleep int main() { int i = 1; while(1) // while(1) 은 참이다. { printf("%c", '.'); // 화면에 . 을 출력해라. fflush(stdout); // 버퍼에 있는 모든 데이터를 강제로 출력시킨다. sleep(1); } return 0; } -- test3.c -- # gcc -o test3 test3.c # ./test3 & [1] 31179 .... # kill 31179 [1]+ Terminated ./test3 - Unix(Linux 포함)에서는 C 언어에서 signal을 사용하기 위해서는 signal 함수를 이용한다. # vi test3.c -- test3.c -- #include <stdio.h> // printf #include <unistd.h> // sleep #include <signal.h> // signal void signal_handler(); // 함수 선언 int main() { int i = 1; // SIGTERM 시그널을 받으면 signal_handler 함수를 호출한다. signal(SIGTERM, (void *)signal_handler); // 함수 호출 while(1) { printf("%c", '.'); fflush(stdout); sleep(1); } return 0; } void signal_handler() // 함수 정의 { printf("%s", "^^*"); } -- test3.c -- # gcc -o test3 test3.c # ./test3& [1] 31227 ..... # kill 31227 ^^* ..... # kill -9 31227 [1]+ Killed ./test3 =========================================================================
o signal(신호) ----------+------------------------------------------------- 시그널명 | 설명 ----------+-------------------------------------------------
SIGHUP | 터미널을 읽어버렸을때 발생한다.
SIGABRT | 프로그램의 비정상종료시 발생한다.
SIGINT | Control-C 나 DELETE 키를 입력했을때 발생한다.
SIGKILL | 프로세스를 죽이기 위해서
SIGPIPE | 단절된 파이프에 write 할경우 발생
SIGSEGV | 잘못된 메모리 참조(주로 포인터를 잘못 썼을때)
SIGSTOP | 프로세스의 일시중단 (Ctrl+z)
SIGSUSR1 | 사용자를 위해 정의된 시그널
SIGCONT | 중지된 프로세스를 다시 시작한다.
SIGSTOP | 실행된 프로세스를 중지 시킨다.
: : ----------+-------------------------------------------------
2. C 언어를 이용한 SIGHUP 시그널을 처리하기
#include<stdio.h> #include<unistd.h> #include<signal.h> void signal_handler(); void sighup_handler(); int main(int argc, char argv[]) { int i = 1; // SIGTERM 시그널을 받으면 signal_handler 함수를 호출한다. signal(SIGTERM, (void *)signal_handler); // signal(받을 signal 종류, 함수포인터); signal(SIGHUP, (void *)sighup_handler); while(1) { printf("%d : %c\n",i ,'.'); fflush(stdout); // 버퍼에 있는 데이터를 강제로 모두 출력한다. sleep(1); signal(SIGHUP, (void *)sighup_handler); } return 0; } void signal_handler() { printf("%s", "^^*"); } void sighup_handler() { FILE *fp; fp = fopen("/tmp/sighup.txt", "w"); fprintf(fp, "SIGHUP 시그널 발생"); fclose(fp); }
===> logout 명령어 or exit 으로 종료하지 말고 x버튼을 눌러서 종료할 것.
그렇게 되면 /tmp 디렉토리 밑에 sighup.txt 파일이 생긴다.
================================================================================================================================================== PROC-LAB> 18, 19 signal 을 이용해서 프로세스를 중지/시작 시켜보자. # vi 1.txt & [1] 31677 [1]+ Stopped vim 1.txt # ps aux| grep 1.txt root 31677 0.0 0.9 9544 2348 pts/1 T 13:32 0:00 vim 1.txt root 31679 0.0 0.2 4032 684 pts/1 R+ 13:32 0:00 grep 1.txt- 동작중인 프로세스에서 ^z 를 누르면 19번 signal이 발생되서 프로세스가 중지된다.
# ./test2.sh ..... <-- Ctrl + Z [2]+ Stopped ./test2.sh # ps aux| grep test2.sh root 31686 0.0 0.4 4600 1032 pts/1 T 13:33 0:00 /bin/sh ./test2.sh root 31693 0.0 0.2 4032 684 pts/1 R+ 13:33 0:00 grep test2.sh# ./test2.sh & [3] 31697 ... # ps aux | grep test2.sh root 31686 0.0 0.4 4600 1032 pts/1 T 13:33 0:00 /bin/sh ./test2.sh root 31697 0.0 0.4 4600 1028 pts/1 S 13:34 0:00 /bin/sh ./test2.sh # kill -19 31697 [root@fw ~]# ps aux | grep test2.sh root 31686 0.0 0.4 4600 1032 pts/1 T 13:33 0:00 /bin/sh ./test2.sh root 31697 0.0 0.4 4600 1028 pts/1 T 13:34 0:00 /bin/sh ./test2.sh # kill -18 31697 .... # ps aux | grep test2.sh root 31686 0.0 0.4 4600 1032 pts/1 T 13:33 0:00 /bin/sh ./test2.sh root 31697 0.0 0.4 4600 1028 pts/1 S 13:34 0:00 /bin/sh ./test2.sh=========================================================================
/etc/ssh/sshd_config => ssh 데몬이 사용하는 설정파일
========================================================================= PROC-LAB(?)> SIGHUP 테스트 (데몬) 데몬 프로세스는 SIGHUP(1) 을 받으면 데몬을 재시작한다. 데몬을 재시작한다는 의미는 설정파일을 다시 읽어들인다는 의미이다. # netstat -nltp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 14212/mysqld tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 14556/httpd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2779/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2380/sendmail # vi /etc/ssh/sshd_config -- /etc/ssh/sshd_config -- : : Port 22 Port 1900 Port 2000 : : -- /etc/ssh/sshd_config -- # kill -1 2779 # netstat -nltp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 14212/mysqld tcp 0 0 0.0.0.0:1900 0.0.0.0:* LISTEN 31905/sshd tcp 0 0 0.0.0.0:2000 0.0.0.0:* LISTEN 31905/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 14556/httpd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 31905/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN =========================================================================
========================================================================= PROC-LAB> 데몬 프로그램을 짜보자. 참고 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/%B5%A5%B8%F3(daemon)%20%C7%C1%B7%CE%B1%D7%B7%A5%BF%A1%20%B4%EB%C7%D1%20%C0%CC%C7%D8 데몬 프로그래명 : mydaemon
o 원래 데몬의 모습 실제 웹서버 데몬 프로그램을 실행했을 때 보면 데몬은 아래처럼 쉘에서 명령어를 실행했을 때 터미널에서 분리가 되어 실행된다. 이를 한번 확인해보자. - 웹서버 데몬(httpd)을 중지한다. # /etc/init.d/httpd stop # netstat -nltp | grep :80 - httpd 의 명령어가 터미널에서 분리 되므로 쉘에서 실행 후에 바로 쉘에 떨어지는 것이다. # /usr/sbin/httpd # netstat -nltp | grep :80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 32600/httpd # ps aux | grep httpd root 32600 0.0 1.1 10108 2936 ? Ss 15:11 0:00 /usr/sbin/httpd apache 32601 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32602 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32603 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32604 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32605 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32606 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32607 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd apache 32608 0.0 0.8 10108 2060 ? S 15:11 0:00 /usr/sbin/httpd# cd # vi mydaemon.c -- mydaemon.c -- #include <stdio.h> #include <unistd.h>
int main() {
while(1)
sleep(1); return 0; } -- mydaemon.c --
===> 데몬은 쉘에서 명령어를 실행할 때 터미널에서 분리가 되야한다.
위의 프로그램은 터미널에서 분리를 못하기 때문에 멈춰있는 것이다.
(부모 프로세스인 bash가 wait 상태이기 때문에 mydaemon이 종료할 때 까지 기다린다.)
- 데몬이 되기 위해서 소스를 수정한다. # vi mydaemon.c -- mydaemon.c -- #include <stdio.h> #include <unistd.h> // fork, sleep, setsid, chdir #include <stdlib.h> // exit int main() { pid_t pid; pid = fork(); // 자식 프로세스를 생성하지 못했다면 에러를 출력하고 프로그램 종료 if(pid == -1) { perror("fork: "); exit(1); } // 부모 프로세스를 종료한다. if(pid > 0) exit(1); chdir("/"); // 프로세스가 루트디렉토리에서 작업을 수행하도록 변경 setsid(); // 새로운 세션을 만들고, 자식 PID가 세션의 제어권을 가지도록 한다 // 실제 서비스할 코드를 나중에 이 부분에 넣는다. while(1) sleep(1); // 1초 대기 return 0; } -- mydaemon.c -- # gcc -Wall -o mydaemon mydaemon.c # ./mydaemon # ps aux|grep mydaemon root 32756 0.0 0.0 1620 168 ? Ss 15:28 0:00 ./mydaemon ~~~ =========================================================================
========================================================================= PROC-LAB> 인터넷 슈퍼 데몬을 이용해서 telnet server를 설치해보자. Linux 에서 서비스(데몬) 를 실행시키는 두 가지 방법 1. 독립적인 데몬 (standalone 방식 데몬) 2. 인터넷 슈퍼데몬 (inetd -> xinetd 방식 데몬) ~~~~~~~~~~~~~~~~ 윈도우에서는 없다. -- 순서 -- 1. xinetd 패키지를 설치한다. 2. telnet-server 패키지를 설치한다. 3. telnet server 의 설정을 수정한다. 4. xientd 서버를 시작한다. 5. 접속 테스트를 한다. -- 순서 -- 1. xinetd 패키지를 설치한다. - xinetd 패키지를 확인하고 없다면 설치한다. # rpm -qa | grep xinetd # yum -y install xinetd 2. telnet-server 패키지를 설치한다. - telnet server 패키지를 확인하고 없다면 설치한다. # rpm -qa | grep telnet telnet-0.17-39.el5 # yum -y install telnet-server 3. telnet server 의 설정을 수정한다. - disable = yes 를 no 수정한다. # cd /etc/xinetd.d # vi telnet -- telnet -- service telnet { flags = REUSE socket_type = stream wait = no user = root server = /usr/sbin/in.telnetd log_on_failure += USERID disable = no } -- telnet -- 4. xientd 서버를 시작한다. - xientd 를 start 하고 포트를 확인한다. # /etc/init.d/xinetd start # netstat -nltp - 방화벽을 비활성화 한다. # iptables -F 5. 접속 테스트를 한다. - 사용자 telnetuser 를 생성하고 로그인을 시도한다. # useradd telnetuser # passwd telnetuser # telnet localhost Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. CentOS release 5.8 (Final) Kernel 2.6.18-371.4.1.el5 on an i686 login: telnetuser Password: $ =========================================================================
========================================================================= LAB> lsof 명령어 lsof 명령어 활용법 글쓴이 : 윤영한(master@ilinuxbay.com) 작성일 : 2005-02-21 카피라이트 : 리눅스베이교육센터, 윤영한 목차 1. lsof 란? 2. lsof 활용법 3. 해킹 추적 4. 결론 ____ 1. lsof 란? # whatis lsof lsof (8) - list open files ( 열려진 파일들을 보는 명령어 ) 일반적으로 시스템에서 동작하고 있는 모든 프로세스에 의해서 열리어진 파일들에 관한 정보를 보여주는 시스템 관리 명령어 2. lsof 활용법 2.1. lsof 파일명 지정한 파일을 엑세스 하고 있는 프로세스의 정보를 보여준다. ]# lsof /usr/sbin/proftpd COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME proftpd 647 nobody txt REG 8,2 433516 209221 /usr/sbin/proftpd 2.2. lsof /tmp 지정한 디렉토리를 엑세스 하고 있는 프로세스의 정보를 보여준다. ]# lsof /tmp COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME libhttpd. 27187 root 3u REG 7,0 0 13 /tmp/ZCUD5mDv1l (deleted) libhttpd. 27318 nobody 3u REG 7,0 0 13 /tmp/ZCUD5mDv1l (deleted) libhttpd. 27319 nobody 3u REG 7,0 0 13 /tmp/ZCUD5mDv1l (deleted) libhttpd. 27320 nobody 3u REG 7,0 0 13 /tmp/ZCUD5mDv1l (deleted) libhttpd. 27321 nobody 3u REG 7,0 0 13 /tmp/ZCUD5mDv1l (deleted) 2.3. lsof -i 모든 네트워크 연결되어 있는 프로세스와 파일을 정보를 보여준다. ]# lsof -i sshd 586 root 3u IPv4 1877 TCP *:ssh (LISTEN) xinetd 600 root 5u IPv4 1943 TCP *:pop3 (LISTEN) sendmail 619 root 4u IPv4 1962 TCP *:smtp (LISTEN) proftpd 647 nobody 0u IPv4 315947 TCP *:ftp (LISTEN) mysqld 708 mysql 3u IPv4 2652 TCP *:mysql (LISTEN) ex)lsof -iTCP ; lsof -iUDP tcp 나 혹은 UDP를 걸러서 볼때 사용한다.
2.4. lsof -c 데몬명 지정한 데몬과 연결되어 있는 프로세스와 파일을 정보를 보여준다. # tty /dev/pts/2 # lsof -c mydaemon COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mydaemon 753 root cwd DIR 253,0 4096 3506177 /tmp mydaemon 753 root rtd DIR 253,0 4096 2 / mydaemon 753 root txt REG 253,0 5434 1738092 /root/mydaemon mydaemon 753 root mem REG 253,0 130860 4431704 /lib/ld-2.5.so mydaemon 753 root mem REG 253,0 1706232 4431705 /lib/libc-2.5.so mydaemon 753 root 0u CHR 136,2 0t0 4 /dev/pts/2 mydaemon 753 root 1u CHR 136,2 0t0 4 /dev/pts/2 mydaemon 753 root 2u CHR 136,2 0t0 4 /dev/pts/2 # ls -l /proc/753/fd total 0 lrwx------ 1 root root 64 Apr 18 16:57 0 -> /dev/pts/2 lrwx------ 1 root root 64 Apr 18 16:57 1 -> /dev/pts/2 lrwx------ 1 root root 64 Apr 18 16:57 2 -> /dev/pts/2 # cp mydaemon.c mydaemon2.c # vi mydaemon2.c -- mydaemon2.c -- : : close(0); close(1); close(2); : -- mydaemon2.c -- # gcc -o mydaemon2 mydaemon2.c # ./mydaemon2 # ps aux | grep mydaemon2 root 811 0.0 0.0 1620 168 ? Ss 17:05 0:00 ./mydaemon2 # lsof -c mydaemon2 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mydaemon2 811 root cwd DIR 253,0 4096 3506177 /tmp mydaemon2 811 root rtd DIR 253,0 4096 2 / mydaemon2 811 root txt REG 253,0 5552 1738097 /root/mydaemon2 mydaemon2 811 root mem REG 253,0 130860 4431704 /lib/ld-2.5.so mydaemon2 811 root mem REG 253,0 1706232 4431705 /lib/libc-2.5.so- 정적으로 실행파일을 컴파일하고 데몬을 실행시키면 ~~~.so 파일이 없다. # gcc -static -o mydaemon3 mydaemon2.c # ls -l mydaemon2 -rwxr-xr-x 1 root root 5552 Apr 18 17:05 mydaemon2 # ls -l mydaemon3 -rwxr-xr-x 1 root root 585422 Apr 18 17:08 mydaemon3 # ./mydaemon3 # ps aux | grep mydaemon3 root 855 0.0 0.0 752 52 ? Ss 17:08 0:00 ./mydaemon3 root 857 0.0 0.1 1956 500 pts/2 R+ 17:08 0:00 grep mydaemon3 # lsof -c mydaemon3 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mydaemon3 855 root cwd DIR 253,0 4096 3506177 /tmp mydaemon3 855 root rtd DIR 253,0 4096 2 / mydaemon3 855 root txt REG 253,0 585422 1738100 /root/mydaemon32.5. lsof -p 프로세스ID 지정한 프로세스와 관련된 프로세스와 파일의 정보를 보여준다. # lsof -p 1 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root cwd DIR 8,3 4096 2 / init 1 root rtd DIR 8,3 4096 2 / init 1 root txt REG 8,3 27036 16204 /sbin/init init 1 root mem REG 8,3 1571340 95813 /lib/tls/libc-2.3.2.so init 1 root mem REG 8,3 106424 15973 /lib/ld-2.3.2.so init 1 root 10u FIFO 8,3 71415 /dev/initctl
# ps PID TTY TIME CMD 874 pts/2 00:00:00 ps 32226 pts/2 00:00:00 bash <-- bash 를 확인해보자. # lsof -p 32226 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 32226 root cwd DIR 253,0 4096 1736705 /root bash 32226 root rtd DIR 253,0 4096 2 / bash 32226 root txt REG 253,0 735804 1114171 /bin/bash bash 32226 root mem REG 253,0 50848 4423720 /lib/libnss_files-2.5.so bash 32226 root mem REG 253,0 130860 4431704 /lib/ld-2.5.so bash 32226 root mem REG 253,0 1706232 4431705 /lib/libc-2.5.so bash 32226 root mem REG 253,0 20668 4431709 /lib/libdl-2.5.so bash 32226 root mem REG 253,0 13084 4431706 /lib/libtermcap.so.2.0.8 bash 32226 root mem REG 253,0 56458576 4168210 /usr/lib/locale/locale-archive bash 32226 root mem REG 253,0 25462 4260334 /usr/lib/gconv/gconv-modules.cache bash 32226 root 0u CHR 136,2 0t0 4 /dev/pts/2 bash 32226 root 1u CHR 136,2 0t0 4 /dev/pts/2 bash 32226 root 2u CHR 136,2 0t0 4 /dev/pts/2 bash 32226 root 255u CHR 136,2 0t0 4 /dev/pts/23. 해킹 추적
3.1. 시나리오 #lsof -i -> 기본 포트연것을 확인한다. #lsof -p -> 프로세스를 분석한다. #lsof /home/홈페이지 디렉토리 -> 특정디렉토리에 있는 프로세스 검사 #lsof /tmp -> 임시파일 관련 프로세스 분석 #lsof /dev -> 정규 해킹 디렉토리 분석 각종 정보를 수집해고 정리 및 대응을 한다. 4. 결론 보안 관련된 일을 하는 사람은 반드시 마스터해야한다. =========================================================================
참고 사이트 :
sysinternals.com // download에 Sysinternals Suite 다운로드
ipconfig.co.kr // ip 찾아보기