구축 환경 VirtualBox - Fedora 15 (kernel : 2.6.40.4-5.fc15.i686.PAE) 작동 원리 chroot유저 ssh 접속 -> 접속유저의 홈디렉토리 밑.ssh의 rc 파일 실행 -> daemonstart실행 -> daemon 작동 -> 접속 유저만의 Jail 디렉토리 생성 -> 접속 유저의.bashrc 의 chroot 명령어 실 행 -> V_Jail 접속 완료 chroot 구축에 필요한 파일 목록 /chroot/bin/ /chroot/dev/ /chroot/home/ : null zero : Jail을 이용할 사용자 홈디렉토리
/chroot/lib/ /chroot/etc/
/chroot/usr/bin/ /chroot/usr/lib/ /chroot/usr/share/ (아래 두 디렉토리를 원본그대로 Copy )
V_Jail - Daemon & Daemonstart Code & fifo.h Code - fifo.h - #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> #define SV_FIFO_NAME "/tmp/fifo/sv_fifo" #define CL_FIFO_NAME "/tmp/fifo/cl_%d_fifo" struct data_to_pass_st pid_t client_pid; ;
- Daemon.c - #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdlib.h> #include "fifo.h" #include <ctype.h> void hand(int signum); int main() pid_t pid; if (( pid = fork()) < 0) exit(0); else if(pid!= 0) exit(0); signal(sighup, SIG_IGN); close(0); close(1); close(2); setsid(); while(1) struct sigaction act; sigset_t set; sigemptyset(&(act.sa_mask));
sigaddset(&(act.sa_mask), SIGUSR1); act.sa_handler = hand; sigaction(sigusr1, &act, NULL); sleep(1); void hand(int signum) if(signum == SIGUSR1) int sv_fifo_fd, cl_fifo_fd; struct data_to_pass_st fifo_data; int read_res; char cl_fifo[256]; char path_1[128]; char path_2[128]; char mnt[128]; // 아래이미지에없는것. 새로추가됨 mkfifo(sv_fifo_name, 0777); sv_fifo_fd = open(sv_fifo_name, O_RDONLY); if (sv_fifo_fd == -1) exit(exit_failure); while(1) read_res = read(sv_fifo_fd, &fifo_data, sizeof(fifo_data)); if (read_res > 0) sprintf(cl_fifo, CL_FIFO_NAME, fifo_data.client_pid); cl_fifo_fd = open(cl_fifo, O_WRONLY);
if(cl_fifo_fd!= -1) sprintf(path_1, "mkdir /V_Jail/%d", fifo_data.client_pid); sprintf(path_2, "cp rfp /chroot/* /V_Jail/%d", fifo_data.client_pid); sprintf(mnt, "mount -t proc /proc/ /V_Jail/%d/proc", fifo_data.client_pid); // 아래이미지에없는것. 새로추가됨 system(path_1); system(path_2); system(mnt); write(cl_fifo_fd, &fifo_data, sizeof(fifo_data)); close(cl_fifo_fd); close(sv_fifo_fd); unlink(sv_fifo_name); exit(exit_success);
- Daemonstart.c #include "fifo.h" #include <ctype.h> int main() system("sudo kill -10 1234"); // 1234란에는 Daemon 의 PID 입력 int sv_fifo_fd, cl_fifo_fd; struct data_to_pass_st fifo_data; char cl_fifo[256]; sv_fifo_fd = open(sv_fifo_name, O_WRONLY); if(sv_fifo_fd == 1) printf("fail_1"); exit(exit_failure); fifo_data.client_pid = getppid(); sprintf(cl_fifo, CL_FIFO_NAME, fifo_data.client_pid); if(mkfifo(cl_fifo, 0777) == -1) printf("fail_2"); exit(exit_failure); write(sv_fifo_fd, &fifo_data, sizeof(fifo_data)); cl_fifo_fd = open(cl_fifo, O_RDONLY); if(cl_fifo_fd!= -1) if(read(cl_fifo_fd, &fifo_data, sizeof(fifo_data)) > 0 ) // 이부분은 IPS가성공했을때실행할코드 close(cl_fifo_fd);
close(sv_fifo_fd); unlink(cl_fifo); exit(exit_success);
V_Jail 을사용할사용자의 rc(~/.ssh/rc) Code &.bashrc - rc #!/bin/bash trap "" 2 3 9 echo "Connecting...Please Wait..." sudo /home/chroottest/.ssh/fifotest2 & # 위경로는 fifotest2 가있는경로로바꿀수있음. while [ 1 ] do if [ -d /V_Jail/$! ] && [ -e /V_Jail/$!/etc/passwd ] && [ -d /V_Jail/$!/home/chroottest ] && [ -d /V_Jail/$!/usr/share/vim/vimfiles/tutor ] && [ -e /V_Jail/$!/usr/bin/whoami ] then echo "Welcome!!" echo $! >./.ssh/ppid break; fi done
-.bashrc - #.bashrc trap "" 2 3 9 # Source global definitions if [ -f /etc/bashrc ]; then. /etc/bashrc fi # User specific aliases and functions var=$(echo $SSH_TTY awk -F/ 'print $4') ppid=$(cat.ssh/ppid_$var) chroot --userspec=chroottest:jail /V_Jail/$ppid /bin/bash # --userspec 의내용은사용할사용자의정보로바꾸어야함 visudo 의추가내용 chroottest NOPASSWD:/home/chroottest/.ssh/fifotest2, ALL=NOPASSWD:/bin/kill, NOPASSWD:/bin/chown, NOPASSWD:/bin/chmod
V_Jail 을사용할사용자의 rc(~/.ssh/rc) Code( 수정 : 종료기추가 ) - rc (if 문안에있는 echo 들은빼도상관없음 ) #!/bin/bash trap "echo Warning! Invalid Command!" 2 3 9 echo "Connecting...Please Wait..." sudo /home/ctest/.ssh/connecter-1.0 & var=$(echo $SSH_TTY awk -F/ 'print $4') echo $! >.ssh/ppid_$var while [ 1 ] do if [ -d /V_Jail/$! ] && [ -e /V_Jail/$!/etc/passwd ] && [ -d /V_Jail/$!/home/chroottest ] && [ -d /V_Jail/$!/usr/share/vim/vimfiles/tutor ] && [ -e /V_Jail/$!/usr/bin/whoami ] then #exit 만드는부분 #var=$(echo $SSH_TTY awk -F/ 'print $4') echo "1" ptsnum=$(echo $SSH_TTY awk -F/ 'print $4') echo "2" ptsps=$(ps -ef grep pts/"$ptsnum" grep sshd awk 'print $2' head -1) echo "3" cp /home/ctest/exitfirst.c /V_Jail/$!/bin/ echo "3-2" sed "s/ptsps/$ptsps/g" /V_Jail/$!/bin/exitfirst.c > /V_Jail/$!/bin/exitsecond.c echo "4" gcc -o /V_Jail/$!/bin/exit /V_Jail/$!/bin/exitsecond.c echo "5" rm -rf /V_Jail/$!/bin/exitfirst.c /V_Jail/$!/bin/exitsecond.c echo "6"
sudo chmod o-w /V_Jail/$!/bin break; fi done * 여기까지접속관련 * * 주의 : V_Jail이란디렉토리와 chroot라는디렉토리는 / 밑에있음 * * 주의 : /chroot/ 안에는맨위의필요한파일들이들어있어야함 * * 주의 : /V_Jail/ 퍼미션주의 * * 참고 : /chroot/bin 퍼미션은 757 이어야함 ( 접속계정권한문제 ) * * ^D 해결해야됨 *