Level10을 들어가서 hint를 입력하면 다음과 같이 나옵니다.



두 명의 사용자가 대화방을 이용하여 비밀스런 대화를 나누고 있다.

그 대화방은 공유 메모리를 이용하여 만들어졌으며,

key_t의 값은 7530이다. 이를 이용해 두 사람의 대화를 도청하여 level11의 권한을 얻어라.

 

이번 문제는 공유 메모리를 도청하는 문제로 보입니다.

 

공유 메모리는 여러 프로세스가 같이 쓰는 메모리를 말합니다. 이 기술을 이용하면 프로세스 끼리 통신을 할 수 있으며, 같은 데이터를 공유할 수 있습니다.

같은 메모리 영역을 공유하기 위해서는 공유메모리를 생성한 후 프로세스 자신의 메모리를 사용하듯 사용하면 됩니다.

 



ipcs를 쓰면 현재 사용하고 있는 공유 메모리의 정보가 출력됩니다.

Key: 0x1D6A(7530)

Owner: root

Perms: 666

Bytes: 1028

 

권한이 666으로 되어 있으니 모든 사용자가 볼 수 있겠군요.

C언어로 공유메모리 접근 프로그래밍을 해줍니다.


http://forum.falinux.com/zbxe/index.php?document_srl=423456&mid=C_LIB

코드는 위 링크를 참고하여 작성했습니다.

 

컴파일 한 후 프로그램을 돌리면 level11 암호가 출력됩니다.



Level11의 암호는 what!@#$?이네요.

 

공유메모리를 사용할때는 권한 설정을 잘 해야겠습니다.

Level9 로그인하고 힌트를 확인해 봅니다.



/usr/bin/bof의 코드를 주고 이를 이용해서 level10의 권한을 얻으라고 하네요.

파일 이름도 그렇고 코드 내용을 봤을 때 buffer overflow를 이용하여 문제를 풀으라고 하는것 같네요.

 

Buffer Overflow란 메모리의 크기보다 더 큰 데이터가 들어와서 다른 메모리에까지 영향을 주는 것을 말합니다.

해킹 공격의 기본이 되는 기법이기도 하죠. Buffer Overflow에 대한 추가 내용은https://ko.wikipedia.org/wiki/퍼_버플로를 참고하시기 바랍니다.

 

프로그램을 실행하면 메모리에 우선 할당이 되는데, 다음과 같은 형식으로 할당이 됩니다.

여기서 함수에서 선언한 지역변수는 stack영역에 들어가게 됩니다. 스택은 위에서부터 아래로 자라므로.

buf2[10]가 들어가고 그 아래에 buf[10]가 할당 되게 됩니다.

즉 프로그램에서 입력을 받아 값을 buf에 넣으므로 만약 buf[10]보다 큰 데이터가 들어오면  buf2[10]에도 영향을 주는 것입니다.

 

여기서 알아야 하는것은 메모리에 값이 들어갈때 어떻게 들어가는 지도 알아야 합니다.

지금 buf2[10]buf[10]은 메모리의 스택영역에 다음과 같이 들어가 있습니다.



메모리에 공간을 할당할때 Full Word Boundary에 맞춰 8의 배수로 할당 되므로, Buf[10]Buf2[10]사이에는 빗금친 6칸의 사용하지 않는 공간이 존재합니다.

 

입력이 buf[10]에 되니깐 만약 01234라는 5자리의 데이터를 집어넣으면 다음과 같이 들어갑니다.



즉 할당된 메모리의 오른쪽부터 값이 들어갑니다. 왜냐하면 메모리의 번지가 낮은쪽 부터 채우기 때문입니다. 그림상에서 왼쪽이 높은 주소이고 오른쪽이 낮은 주소입니다.

 

입력값이 hackerschool ftz level9이라면 10자리가 넘고 Buffer Overflow가 발생해 다음과 같이 들어갑니다.



코드를 보면 strncmp(buf2, “go”, 2) ==0 buf2의 앞 두 글자가 “go”면 권한이 상승이 되고 쉘이 열리게 되어 있네요. 즉 메모리에 go가 다음과 같이 들어가도록 해야 합니다.



이렇게 값이 들어가려면 16자리의 글자 뒤에 go를 붙여 주면 될것 같습니다.

0123456789123456go라고 입력해 보겠습니다.


원했던 Good Skill!이 출력되고 level10권한으로 쉘이 실행됨을 볼 수 있습니다.

이제 my-pass로 비밀번호를 확인하면 level10의 비밀번호를 획득 하실 수 있습니다.

Level10의 비밀번호는 interesting to hack!입니다.

 

사실상 이문제는 go8번 이상 출력하기만 하면 풀리는 문제입니다만, 원리를 확실히 짚고 넘어가시는 것이 좋습니다. 메모리에 프로그램이 할당 되는 것과, 변수가 스택에 어떻게 할당 되는지, full word boundary가 무엇인지 등 중요한 개념이 많이 나오니 꼭 숙지하고 넘어가셨으면 합니다.

Level8 접속하여 우선 힌트를 확인합니다.



level9shadow파일이 서버 어딘가에 숨어있다.

그 파일에 대해 아려진 것은 용량이 “2700”이라는 것 뿐이다.

 

이번 문제는 우선 용량이 2700인 파일을 찾아야 겠네요.

근데 여기서 발생하는 문제는 단위가 무엇인지 모른다는 것입니다.

단위가 b일수도 k일수도 c일수도 있습니다.

 

Find명령어의 메뉴얼을 보면 –size옵션에 대한 설명이 나와있습니다.

 

       -size n[bckw]

              File uses n units of space.  The units are  512-byte  blocks  by

              default  or  if ??b?? follows n, bytes if ??c?? follows n, kilobytes

              if ??k?? follows n, or 2-byte words if ??w?? follows  n.   The  size

              does  not  count  indirect  blocks,  but it does count blocks in

              sparse files that are not actually allocated.

 

단위로 사용할수 있는것은 b, c, k, w가 될것 같습니다.


운좋게 두번만에 찾아졌네요.

4가지 항목 중에서 2번째 /etc/rc.d/found.txt.가 가장 의심스러우니 내용을 확인해 보죠.

 


level9shadow내용이네요.

 

level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524

 

level9계정의 암호가 되는 부분은$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.입니다.

암호화된 이것을 복호화 해주면 level9의 암호가 나오는 것입니다.

암호는 MD5방식으로 암호화 되어 있으니 이를 복호화 해주면 되겠습니다.

 

MD5에 대한 내용은 위키를 참고해주세요 : https://ko.wikipedia.org/wiki/MD5

 

Shadow암호는 John the Ripper라는 프로그램으로 복호화 가능합니다.

http://www.openwall.com/john/에서 자신의 운영체제와 맞는 것을 설치해 주시면 됩니다.

 

John the Ripper를 설치한 후 run폴더 아래에 passwd.txt파일로 shadow내용을 집어 넣습니다.



그리고 터미널을 실행시킨후 run폴더로 들어가 john passwd.txt를 입력합니다.



위와 같이 복호화가 되면 암호를 보여줍니다. 자세히 보기 위해 john –-show passwd.txt를 입력합니다.




shadow형식에 맞춰 암호부분이 복호화 되어 들어나 있음을 알수 있습니다.

Level9의 암호는 apple이네요.

 

파일 사이즈로 find명령어를 사용하는 것과 shadow파일의 형식에 대한 지식, shadow파일을 복호화 하는 방법을 아는 지를 묻는 문제였습니다.

Level7으로 로그인 한 뒤에 힌트를 한번 확인해 봅니다.



/bin/level7 명령어를 실행하면, 패스워드 입력을 요청한다.

1.    패스워드는 가까운 곳에 ..

2.    상상력을 총 동원하라.

3.    2진수를, 10진수를 바꿀 수 있는가?

4.    계산기 설정을 공학용으로 바꾸어라.

 

이번에는 힌트가 좀 많네요.

/bin/level7을 실행하니 암호를 요구합니다.

패스워드가 가까운 곳에 있다고 했으니 level6의 암호 come together을 한번 입력해 보았습니다.



come together은 아닌것 같네요.

근데 이상한 문장이 출력 되었습니다.

_--_--_-   _--____-   _---_-__   _--__-_-

무슨 문장일까요

로컬서버로 구축해서 하시는 경우에는 /bin/wrong.txt파일이 없다는 에러가 뜨는 경우가 있습니다. 이럴 경우에는 해커스쿨 FTZ서버 ftz.hackerschool.org로 접속하셔서 푸는것을 추천드립니다.

 

보니깐 _이루어져 있고 8개씩 나누어져 있습니다.

아마 _0을 의미하는것이고 1을 의미하는게 아닐까합니다.

 

저것을 10으로 변형해주면01101101 01100001 01110100 01100101이 됩니다.

8개씩 4개로 이루어져 있으니 1byte4, 4byte네요.

 

2진수와 10진수의 변환이 힌트였으니 8개로 끊어 10진수로 변환해 보면 109 97 116 101이 됩니다.

 

느낌이 ASCII코드인것 같습니다.

 

ASCII코드란 숫자밖에 모르는 컴퓨터가 문자를 표시하는 방법입니다.

1byte8자리 2진수가 모여 글자 한개를 의미하는 방법입니다.

 



http://ascii.zeemind.com/?hl=ko

 

ASCII테이블을 참고하여 109 97 116 101을 문자로 변경하면 mate라는 4글자 단어가 나옵니다.

 

이를 입력해 보겠습니다.



접근법이 맞았나 보네요.

Level8의 패스워드는 break the world라고 하네요.

 

이번 문제는 2진수와 10진수의 변환 가능과 ASCII의 개념을 알고 있는지를 물어보는 문제였네요.


FTZ level6에 로그인하면 이전의 문제와 달리 힌트가 자동으로 등장합니다.



hint – 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.

아직은 무슨 소린지 모르겠네요.

이 화면에서 아무키나 누르면 다음 화면으로 진행됩니다.


텔넷 접속 서비스 1.하이텔  2.나우누리  3.천리안

2000년대 초반에 존재하던 서비스들이 보이네요.

하이텔을 선택하기 위해 1을 입력 하였습니다.


접속이 거절 되었습니다. 하이텔이나 나우누리로 접속해도 결과는 마찬가지 였습니다.

우선 hint를 한번 짚고 넘어가야겠습니다.

bbs란 예전에 PC 통신 할때 텔넷으로 접속하던 게시판이라 생각하시면 됩니다. 하이텔 나우누리 천리안이 가장 유명했던 bbs들이었죠.

 

위의 사진을 보고 메뉴를 선택하면 나오는 다음 문구는 telnet을 시도할때 나오는 문구입니다.

메뉴를 선택하면 조건에 맞는 ip값이 전달되고 텔넷 명령어가 시작 되는거죠.

1번 메뉴를 눌렀을 때 telnet 203.245.15.76이라는 리눅스 명령어가 실행이 되고 이는 코드상에서 system(“telnet 203.245.15.76”)이런 식으로 구성 되어 있을 겁니다.

 

직접 ip를 집어 넣는 것이면 명령어 구분자 ‘ ; ‘를 이용해서 명령어를 입력할 수 있을 듯 하나 메뉴를 선택 하면 미리 셋팅 되어 있는 명령어가 실행되니 이 방법으론 접근이 쉽지 않을듯 합니다.

 

우리의 목표를 잠시 생각해 보면, level7권한으로 my-pass명령어를 사용해 level7의 명령어를 획득하는게 목표입니다. 근데 로그인하면 자동으로 실행되는 저 프로그램 때문에 아무런 명령어를 입력하지 못하는 상황이네요.

일단 저 프로그램을 종료 시켜서 쉘을 띄우는것이 우선이라 생각됩니다.

 

리눅스에서 실행 프로세스를 죽이는 방법인 Ctrl+C를 눌러봅니다.



ctrl+c는 쓸 수 없다고 하네요.

 

이것 때문에 삽질을 5시간 정도 한것 같네요. Ctrl+d도 해보고 ctrl+z도 해보고 다른 프로세스 인터럽트 방법도 찾아보고하지만 정답은 정말 간단했습니다.

 

저 창이 뜨기 전에 하면 되요.



이처럼 hint가 나왔을때 ctrl+c를 눌러 프로그램을 종료하면 됩니다.

 

그럼 명령어를 입력할수 있는 쉘이 뜹니다.

목록이 뭐있는지 확인하고, 매우 의심스러운 파일의 내용을 확인해보면,



level7의 비밀번호 come together이 나옵니다.

 

굉장히 허탈하고 쉬운 문제였네요.

 

리눅스에서 프로세스를 종료하는 ctrl+c를 알고 있는지에 대한 문제였습니다.

Level4에서 구한 암호를 입력하고 들어가서 우선 파일목록을 한번 봐줍니다.



hint가 보이네요. 당연히 읽어줍시다.



/usr/bin/level5 프로그램은 /tmp 디렉토리에 level5.tmp라는 이름의 임시파일을 생성한다.

이를 이용하여 level6의 권한을 얻어라.

 

우선 /usr/bin/level5를 확인해 봅시다.



level6 setuid가 설정 되어 있네요. 느낌상 저걸 실행하면 my-pass명령어를 통해 level6의 비밀번호를 알 수 있고, 그것이 /tmp/level5.tmp에 저장될 것 같습니다.

/usr/bin/level5를 실행하고 /tmp/level5.tmp에 암호가 있나 확인해봅니다.



/usr/bin/level5를 실행하고 /tmp폴더를 확인해봤는데 level5.tmp는 보이지 않습니다.

아마 /usr/bin/level5프로그램이 종료될 때 임시파일을 지우는 듯 합니다.

 

level5.tmp에 들어있는 내용을 읽는게 이번 level의 문제 요지입니다.

여기서 필요한 공격기법이 레이스 컨디션입니다.

setuid와 임시파일을 듣고 레이스 컨디션을 생각하시면 됩니다.

 

레이스 컨디션을 간단하게 얘기하면 일종의 바꿔치기라 할 수 있습니다. 다른 권한으로 실행되는 프로그램 중간에 끼어들어 자신이 원하는 작업을 하는 기술입니다. 타이밍이 가장 중요하기 때문에 보통 될때까지 실행합니다.

 

레이스 컨디션 공격의 기본적인 아이디어는 다른 권한의 프로그램에 의해 생성되고 사용되는 임시 파일에 대한 것입니다.

 

레이스 컨디션 공격에 앞서 파일 링크라는 개념이 필요한데, 이는 다른 블로그에 잘 정리되어 있으니 여기선 설명하지 않겠습니다.

구글에 리눅스 링크라고만 검색해도 많이 나옵니다.

 

레이스 컨디션 공격을 할때 값을 저장할 임의 파일을 하나 생성을 합니다. 그리고 그 임의 파일의 심볼릭 링크를 생성하여 주는데 이때 이름을 프로그램에서 생성하는 임시파일로 만듭니다. 즉 심볼릭 링크의 이름이 /tmp/level5.tmp가 되는 것이죠.

이렇게 되면 프로그램은 권한 상승이 된 상태에서 링크파일에 데이터를 덮어 씌우고, 그 값이 임의 파일에 저장되게 됩니다.

 

그러나 프로세스 연산과정의 순서로 인하여 권한 상승이 끝난뒤 접근하여 값이 변경 되지 않을 수도 있기 때문에 반복하여 될때까지 하는게 일반적입니다.

 

따라서 프로그램으로 작성하였습니다.

/usr/bin/level5를 반복적으로 실행할 func프로그램입니다.



반복적으로 /tmp/level5.tmp라는 이름의 심볼릭 링크를 생성해주는 link프로그램입니다.



값은 /home/level5/tmp/passwd파일에 저장될 것입니다.

이제 연결을 하나 더 여시고 한쪽에서는 func프로그램을 실행해주고, 다른 한쪽에서는 link프로그램을 실행하여 줍니다.

 

프로그램을 몇초정도 실행하고 ^z로 둘다 멈춘후에 /home/level5/tmp/passwd파일의 내용을 확인하면 level6의 암호가 들어가 있는것을 볼 수 있습니다.


level6의 암호는 what the hell이네요.

레이스 컨디션 공격을 막기 위해서는 먼저 프로그램 로직 중에 임시 파일을 생성한 후, 임시 파일에 접근하기 전에 임시 파일에 대한 심볼릭 링크 설정 여부와 권한에 대한 검사과정을 추가해 주면 됩니다. 

 

이런저런 바쁜일로 정말 오랜만에 포스팅 하네요..

이번엔 FTZ level 4를 풀어보도록 하겠습니다.

서버에 접속해 어느 때와 같이 힌트를 확인해 봅니다.

/etc/xinetd.d/에 누군가 백도어를 심어 놓았다고 하네요.


우선 /etc/xinetd.d가 뭐하는 곳인지 알아봐야겠죠?

/etc/xinetd.d/는 리눅스 인터넷수퍼데몬(xinetd)의 서비스파일들이 들어있는 디렉토리입니다.

xinetd는 인터넷 수퍼데몬(Internet Super Daemon)을 의미하는 것으로서 SENDMAIL, HTTPD 등과 같이 리눅스 시스템에서 실행되는 데몬들 중 하나입니다.
하지만 이 데몬은 리눅스 서버에서 서비스되는 여러 가지 데몬들을 제어하면서 각각 서비스의 연결을 담당하고 있기 때문에 수퍼데몬이라 불립니다.

xinetd에 의해 제어되는 가장 대표적인 서비스 중에는 telnet이 있습니다.
텔넷으로 접속을 시도할 때에는 바로 telnet으로 연결되는 것이 아니라 우선 xinetd에 의해 허가된 사용자인지를 검사합니다.
그리고 xinetdtelnet 설정파일 /etc/xinetd.d/telnet에 정의되어 있는 telnet 서비스데몬과 연결되어 사용자는 telnet 서비스를 비로소 이용하게 됩니다.


/etc/xinetd.d를 한번 확인해 보도록 합시다.

들어갔더니 버젓이 backdoor라는 파일이 보이네요. 내용을 확인해 봅시다.


백도어라 해서 들어가 봤더니 서비스 이름이 finger로 되어있네요.

각 속성들의 의미하는 바는 아래 표와 같습니다.(더 많은 정보는 xinetd.conf메뉴얼을 참고)

속성

값 및 설명

disable

나열된 서비스 값들이 실행되지 못하도록 지정.

enable 속성과 같이 존재하면, enable 속성은 무시.

flags

REUSE : 포트가 사용중(TIME_WAIT)의 경우에서도 재이용할 수 있도록 지원

INTERCEPT : 패킷 전송을 중단해, 허가된 발신처로부터 오고 있는지 확인

NORETRY : 인증에 실패할 경우 같은 서비스에 접속을 허가하지 않음.

IDONLY : 리모트 호스트로 인증되는 유저의 경우만 접속을 허가(로그 옵션의 USERID와 병용 필요)

NAMEINARGS : tcpd를 사용하는 경우에, server_arg로 지정하는 변수가 서비스에 인수(argv[0])으로 받은.

NODELAY : TCP 접속의 경우, TCP_NODELAY 플래그를 셋(set)

DISABLE : 서비스가 실행되지 않게 한다.

KEEPALIVE : TCP 접속의 경우, keep_alive가 셋(set)

 

socket_type

4가지 선택 가능한 값이 있다.

stream : stream 기반의 서비스

dgram : datagram 기반의 서비스

raw : 아이피에 직접 접근을 요하는 서비스

seqpacket : 신뢰성 있는 연속적인 데이터그램 전송을 요구하는 서비스

wait

서비스가 단일 스레드인지, 다중 스레드인지를 결정하는 플래그로 yes는 단일, no는 다중 스레드

user

서버 프로세스를 실행할 수 있는 사용자의 ID를 나타내는 것으로 슈퍼유저일 경우에만 효과를 낼 수 있음.

server

해당 서비스를 실행할 데몬 프로그램의 위치 지정.

log_on_failure

서버가 리소스 부족으로 시작될 수 없거나 설정 파일 내의 규칙에 의한 접근이 거부되었을 때 기록될 값들을 지정.

다음의 4가지 값을 조합 지정 가능.

HOST : 원격 호스트의 IP

USERID : 원격 사용자의 ID

ATTEMPT : 실패한 시도가 있을 경우

RECORD : 클라이언트에 대한 가능한 정보


finger 서비스는 시스템의 사용자정보를 확인하는 서비스입니다.
(자세한 내용은 http://korea.gnu.org/manual/release/finger/finger-ko_3.html 를 참고하시면 됩니다.ㅎ)

설정에 따르면 finger 서비스를 실행하면 level5의 권한으로 /home/level4/tmp/backdoor을 실행합니다.



디렉토리의 내용을 살펴봤는데 역시나 없네요.ㅎㅎ
(저의 경우에는 개인 구축을 했기때문에 파일이 없습니다. 해커스쿨 서버에서 하시는 분들은 파일이 있을 수도 있습니다.)


없으니 만들어 줍시다.

#cd /home/level4/tmp를 통해 해당 디렉토리로 이동하구요.
#vi backdoor.c를 통해 파일 작성을 합니다.

i를 눌러서 편집모드로 들어간후 명령어를 쭉 처준 뒤에
esc를 눌러서 명령모드로 들어가 wq를 입력해 저장 후 종료하면 됩니다.
(vi사용법은 https://mirror.enha.kr/wiki/vi에서...... ㅎㅎ)

간단한 C코드로 my-pass 명령어를 실행하라는 프로그램입니다.


코드를 짰으면 이제 컴파일을 할 차례이겠지요?

gcc를 이용해 컴파일을 해주면 됩니다.


이제 준비는 다 되었구요.
finger 서비스는 79번 포트를 기본으로 사용하고 있습니다.

원격 접속할때 79번 포트로 접속하면 바로 서비스를 이용할 수 있지요.


그럼 이제 finger 서비스를 이용하면 아까 짠 코드를 통해 비밀번호를 알 수 있을것입니다.

따로 접속하기 귀찮으니 그냥 바로 telnet으로 로컬 호스르틀 접속하도록 합시다. ㅎㅎ


짜잔!!

드디어 Level5의 암호를 얻었습니다.

암호는 what is your name?입니다.


수고하셨습니다. 조만간 level5 문제 풀이로 돌아오겠습니다.

level2를 풀고 얻은 password를 가지고 로그인을 하면 역시나 hint가 보입니다.

당연히 hint를 확인 해주어야겠죠.


힌트가 뭔가 길어졌습니다.

단순히 문장 한줄이었던 예전과 다르게 이번엔 autodig의 소스코드가 주어졌네요.

일단 소스코드를 분석해 봅시다.


우선 argc란 프로그램을 실행할 때 넘겨주는 인자의 개수를 말합니다.
$ ls -s / 라고 프로그램을 실행하였다면 총 3개의 인자값을 가지게 됩니다.
argc[0] = ls
argc[1] = -s
argc[2] = /
이렇게 총 3개의 인자값을 갖게 되죠. argc[0]는 항상 프로그램 자기자신을 가르킵니다.

소스를 보면 if( argc!=2 )가 보입니다.
argc의 개수가 2가 아니라면 if문 내부를 실행하는 것이죠.
if문 내부에 exit(0);가 보이는 것으로 보아 if문은 실행하면 안될 것 같습니다.

if문 이후를 보면 strcpy이 나오고, strcat2개가 나오고 system(cmd)가 보입니다.

strcpy의 형태는
char* strcpy(char * dest, cont shar * src)인데
이함수는 src의 문자열을 dest로 복사하는 것입니다.
즉, strcpy( cmd, "dig @" );는 "dig @"문자열을 cmd에 복사하는 것이 되겠습니다.

다음 나오는 strcat의 형태는
char * strcat( char * dest, const char * src)인데
이 함수는 src의 문자열을 dest에 담겨있는 문자열 뒤에 붙이는 것입니다.
즉 strcat( cmd, argv[1] ); 이므로 cmd는 "dig @argv[1]"라는 문자열이 담기게 되는것입니다.

다음 strcat( cmd, " version.bind chaos txt")까지 실행하게 되면,
cmd안에는 "dig @argv[1] version.bind chaos txt"라는 문자열이 담기게 되는것입니다.

그리고 그 다음 system( cmd ); 함수를 통해 cmd안에 담긴 문자열을 쉘에서 명령어로 입력하게 됩니다.
즉, $ dig @argv[1] version.bind chaos txt가 되는 것이죠.


여기서 잠깐 dig함수에 대해 알아보고 가면(사실 dig함수는 문제를 푸는데는 큰 의미는 없습니다만.. 일단 나왔으니...)

dig란 Domain Information Groper의 약자로 dns 진단용 유틸리티입니다.

dig 명령어는 기본적으로 다음과 같은 문법 형식을 갖고 있습니다.

$ dig @ [서버] [도메인] [쿼리형태]


쿼리형태

a : 네트워크 주소

any : 특정 도메인에 대한 모든 정보

mx : 도메인의 메일 교환

ns : 네임서버

soa : Zone파일 상단의 authority 레코드

hinfo : 호스트 정보

axfr : Zone 파일 교환(transfer)

txt : txt


$ dig를 실행하면 윗 사진과 같이 나오는데 각 필드의 뜻은 다음과 같습니다.

;; QUESTION SECTION:
- DNS 질의 내용을 표시

;; ANSWER SECTION:
- DNS 질의 사항에 대한 DNS 응답 RR(Resource Record)을 표시

;; AUTHORITY SECTION:
- DNS 응답 RR이 속한 도메인 존의 NS RR 정보

;; ADDITIONAL SECTION:
- 부가적인 RR 정보를 표시

;; Query time:
- DNS 질의 메시지 발송시점에서 응답시점까지의 소요시간

;; SERVER:
- DNS 응답 메시지를 보내온 질의응답 네임서버

;; WHEN:
- DNS 응답 메시지를 받은 시점의 date & time

;; MSG SIZE rcvd:
- 응답받은 DNS 메시지의 size표시 (byte단위)
IP TCP/UDP 헤더는 제외된 size

autodig를 통해 만들어진 명령어(dig @argv[1] servion.bind chaos txt]는 dns의 bind 버전을 알아내는데 사용되는 명령어입니다.


다시 문제풀이로 돌아가 소스의 추가 힌트 2개를 보겠습니다.
추가 힌트는
- 동시에 여러 명령어를 사용하려면?
- 문자열 형태로 명령어를 전달하려면?
입니다.

- 동시에 여러 명령어를 사용하려면?
동시에 여러 명령어를 사용하려면 명령어 사이에 ;를 넣으면 됩니다.
$ sh; ls이런식인것이죠.
이렇게 하면 sh실행이 종료된후 ls를 실행하게 됩니다.

- 문자열 형태로 명령어를 전달하려면?
문자열 형태로 명령어를 전달하려면 명령어를 큰따옴표("")로 묶어주면 됩니다.


그럼 autodig에 인자를 넘겨줘 봅시다.

$ autodig "168.126.63.1;my-pass"라 입력하겠습니다.


이렇게 하면 autodig 168.126.63.1이 실행된후 my-pass가 실행 되겠죠.

빙고 암호가 나왔습니다.

암호는 suck my brain입니다.


level3의 암호가 나올 거라 예상했는데 level4의 암호가 나온것으로 보아 autodig는 level4로 setUID가 되어 있나봅니다.
한번 확인해 보겠습니다.

확인 결과 예상대로 autodig는 level4에 setUID가 걸려 있음을 확인할 수 있었습니다.


Level1을 클리어 하고 얻은 password를 가지고 level2를 접속했더니 level1과 마찬가지로 hint가 보이는군요.
친절하게 hint를 제공해주셨기에 당연하게 열어보겠습니다.


"텍스트 파일 편집 중 쉘의 명령을 실행시킬 수 있다는데...."라는 힌트가 제공되는군요.


여기서 말하는 텍스트 파일 편집은 vi를 생각하시면 됩니다.
vi(vim)이란 리눅스에서 제일 기본이 되는 텍스트 편집기입니다. 윈도우의 메모장(notepad)와 같은 역할을 하신다고 보시면 됩니다.

GUI기반인 메모장과 달리 CLI기반인 vi는 크게 3가지의 모드가 있습니다.
1. 입력모드 : i, e, o, I, A, O를 누른후 텍스트를 입력할수 있는 상태
2. 명령모드 : esc키를 누른 상태
3. 콜론(ex)모드 : 명령모드 상태에서  :(콜론)을 입력한 상태

그리고 이러한 기본적인 모드들을 메모장의 기능과 비교해보면 다음과 같습니다.
1. 입력모드 : 타이핑을 하여 파일의 내용을 입력하는 모드
2. 명령모드 : 편집 메뉴에서 제공하는 복사, 붙이기, 삭제 등의 편집기능을 활용하는 모드
3. 콜론(ex)모드 : 다른 편집기의 파일 메뉴에서 수행하는 열기, 저장, 다른 이름으로 저장 등의 명령 수행
각 모드의 자세한 사용법은 vi 위키 참고(http://ko.wikipedia.org/wiki/Vi)


여기서 문제를 푸는데 핵심인 모드는 콜론(ex)모드입니다.
클론모드의 핵심중 하나는 :sh를 입력할 경우 쉘 창을 띄워 리눅스 명령어를 입력 할 수 있다는 것인데요.
이때 쉘의 권한은 vi를 실행할때 사용자 권한과 같이 갑니다.


그럼 한번 해보도록 하죠.
$ vi를 입력해 vi창을 띄운후 콜론모드에서 sh를 입력해 쉘을 띄우겠습니다.


아래를 보시면 쉘이 띄워짐을 알수 있습니다.


whoami 명령어를 통해 현재 사용자가 누구인지 한번 보도록 하겠습니다.


확인 결과 현재 사용자는 whoami로 나왔습니다. level2사용자로 로그인해 실행하였기 때문에 당연한 결과입니다. 
하지만 vi에 setUID가 설정되어 있었다면 setUID가 설정된 계정의 권한으로 실행이 되었겠죠.


따라서 level1의 기억을 되살려 lelve3에 setUID가 걸린것을 찾아보도록 합시다.
$ find / -perm -4000 -user level3 2> /dev/null 명령어를 입력해주면 됩니다.


/usr/bin/editor가 출력되었네요.

/usr/bin/editor을 실행해 보면 vi와 같은 창이 뜹니다.
당황하지 않고 콜론모드에서 sh를 입력해 쉘을 띄워준후 whoami로 사용자를 확인합니다.


빙고! whoami 결과 level3으로 뜨네요
level3의 권한을 획득하였습니다. 그럼 이제 my-pass로 level3의 비밀번호를 획득하면 됩니다.

level3의 암호를 얻었습니다.

암호는 can you fly?입니다.

해커스쿨의 안내에 따라 FTZ level1으로 접속하여 파일 목록을 출력한다.



친절하게 hint라는 파일이 보이므로 hint를 읽어 주도록 하자

level2 권한에 setUID가 걸린 파일을 찾으라고 한다.


여기서 setUID가 뭔지 한번 알아보고 넘어가자

유닉스 파일 시스템에서는 각각의 파일마다 권한이 설정되어 있다.
위에 public_html의 줄을 보면(어두워서 뭐가 public_html인지 모르려나.. 2번째) drwxr-xr-x라고 쓰여 있는것이 보일것이다.

이러한 식으로 되어있는것이 유닉스 파일시스템의 권한이다.

r = 읽기권한
w = 쓰기권한
x = 실행 권한

앞에서부터 첫번째 뒤로 3개 단위로 소유자, 소유자가 속한 그룹, 다른 사용자의 권한을 나타낸다. 첫번째 자리는 d가 있으면 디렉토리, -로 되어있으면 일반 파일이다.

비트로 표현하면 8비트로 r = 4, w = 2, x = 1로 각 숫자를 더해 표현하면 public_html의 권한은 755가 된다.

setUID는 조금 특이한 권한으로 rwsr-xr-x 이런식으로 표현하며, 비트로는 4000으로 나타낸다. 즉, 위 권한은 비트로 표현하면 4755가 된다. 

이밖에 비슷한 기능으로 setGID, Sticky-bit가 있고 2000, 1000으로 표현한다.

setUID는 소유자권한의 x에 s로, setGID는 그룹권한의 x에 s로, Sticky-bit는 다른사용자권한의 x에 t로 표현하게 된다.


setUID가 걸린 파일을 찾기 위해선

find명령어를 사용하면 되는데, -perm 옵션과 -user옵션을 이용하면 된다.
지금 찾고자 하는건 권한이 4000대이고, 사용자가 level2이므로
$ find / -user 사용자이름 -perm -4000이라고 입력하면 된다.


실행을 하고 나면 /bin/ExcuteMe가 보인다.

Permission denied라는 표준 에러가 보이는것이 귀찮다면
$ find / -perm -4000 -user level2뒤에 2> /dev/null을 붙여주면 된다.
2는 표준 에러를 뜻하며
2> /dev/null 은 표준 에러를 null로 리다이렉션 하라는 뜻이다.
즉, 표준에러를 출력하지 않겠다는 뜻이다.


명령어를 다시 입력하면,

훨씬 짧게 나왔다.


이제 /bin/ExcuteMe의 파일 권한을 확인해 보면,

권한이 -rwsr-x---, 소유자가 level2임을 알수 있고 즉 lelvel2에 setUID가 적용 되어있음을 알 수 있다.


사실 이 방법 말고도 tmp폴더안의 test.txt의 내용을 확인해보면 /bin/ExcuteMe가 적혀있다.


/bin/ExcuteMe파일을 찾았으니
$ /bin/ExcuteMe로 파일을 실행하면 다음 화면이 뜬다.



암호를 아는 명령어가 my-pass이지만 그것은 안된다고 하니 쉘을 실행해서 level2의 권한을 획득하자.
쉘의 종류는 sh, bash, ksh, csh 등이 있다.


쉘을 띄운다음 암호를 확인하는 my-pass 명령어를 쓰면 암호를 얻을 수 있다.


암호는 : hacker or cracker이다. 






+ Recent posts