구축 환경

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/ : null zero

/chroot/home/ : 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 ALL=NOPASSWD:/bin/kill, NOPASSWD:/home/chroottest/.ssh/fifotest2, 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 이어야함(접속 계정 권한 문제) *

' 2016년 이전 > Project' 카테고리의 다른 글

ShellInaBox을 이용한 웹SSH  (0) 2014.12.29
드디어..Virtual Jail의 끝이..  (0) 2011.10.14

+ Recent posts