level10 --- interesting to hack!
우선 level9 디렉토리를 보자.
기존과 다른 program 디렉터리가 있다. 무엇인가 확인해 보고 싶지만 권한이 없어 볼 수 없다. 의심을 가지고 hint 파일을 보자.
힌트를 보면 공유 메모리에 대한 개념이 잡혀 있어야 한다는 것을 알 수 있다. 공유 메모리의 개념이 어디서 나왔는지, 공유 메모리의 개념에 대해 알아보자.
공유 메모리란 프로세스 간에 공유해서 쓰는 메모리를 의미한다. 프로세스는 기본적으로 자신만의 메모리 공간만을 사용하도록 설계되어 있다. 하지만 프로그램이 커지면서 프로세스 간에 데이터를 공유해서 사용해야 할 필요성이 생기면서 여러개의 프로세스가 하나의 공유 메모리를 사용하는 상황이 생겼다. 아래의 그림을 보고 쉽게 이해해보자. 공유 메모리를 사용하는 방식은 공유 메모리를 사용할 프로세서 중 하나가 조건을 설정해 공유 메모리를 만들고, 그 외의 프로세스가 필요한 정보를 이용해 공유 메모리를 같이 사용한다.
공유 메모리를 사용하지 않는 방식
공유 메모리를 사용하는 방식
공유 메모리에 대한 개념을 조금이나마 알아 보았다. 이제 힌트를 분석해보자. 우선 평소와 다르게 공격 파일에 대한 힌트가 제시되어 있지 않다. level11 권한으로 SetUID가 걸린 파일을 찾아보자.
하지만 level11 권한으로 SetUID가 걸려있는 파일이 없다는 것을 알 수 있다. 그러면 level10의 권한으로 실행되는 파일을 찾아보자.
level10의 권한으로 실행되는 파일을 보았지만 딱히 의심스러운 파일이 보이지 않는다. 많은 사람들이 여기부터 당황할 수 있다. 하지만 마지막으로 생각해보면 시스템이 시작될 때 자동으로 시작되도록 하는 프로그램이 적혀있는 설정파일에 적혀일 수 있다. rc.local 파일이 시작 관련 실행파일이기 때문에 rc.local 파일을 보자.
즉, 시스템이 시작될 때 /home/level10/program/level10이라는 이름으로 실행된다는 것을 알 수 있다. level10이라는 이름으로 실행되고 있는 프로세스가 있는지 확인해보자.
level10으로 실행되고 있는 프로세스가 없다. 따라서 시스템이 시작될 때 실행되는 level10 프로그램은 프로세스 프로그램이다.
아직, 데몬과 프로세스의 차이를 모를 수 있다. 데몬은 무한히 반복해서 실행되는 프로세스를 말한다. 프로세스는 한 번만 실행되는 프로세스를 말한다.
따라서 ps -ef | grep level10을 하더라도 level10이 프로세스이기 때문에 현재 실행되고 있지 않다. 프로세스의 예로는 엑셀, 워드, 메모장 등이 있다. 데몬의 예는 http, telnet 등이 있다.
공유 메모리에 대해 자세히 알아 보았는데 공격해보기 전에 공유 메모리에 대한 함수에 대해 알아보자.
sgmget() 함수는 공유 메모리를 생성하거나 생성된 공유 메모리를 사용할 수 있는 함수이다.
sgmget() 함수를 사용하기 위해서 <sys/ipc.h>, <sys/shm.h>의 헤더파일을 선언해야 한다. shmget() 함수의 원형은 int shmget(key_t key, int size, int shmflg);이다.
key_t key : 공유 메모리를 읽기 위한 변수이다. int size : 공유 메모리의 크기이다. int shmflg : 공유 메모리 생성이나 사용 옵션을 지정한다. IPC_CREATE 옵션은 공유 메모리를 생성한다는 뜻이고, 0666 옵션은 공유 메모리의 사용권한에 관한 옵션이다. 반환값은 공유 메모리를 생성하거나 생성되어 있는 공유된 메모리의 ID를 반환한다.
shmat() 함수는 이미 할당된 공유 메모리 공간을 다른 프로세스에서 사용할 수 있게 권한을 부여하는 함수이다.
shmat() 함수를 사용하기 위해서 <sys/types.h>, <sys/shm.h>의 헤더파일을 선언해야 한다. shmat()의 원형은 void xshmat(int shmid, const void xshmaddr, int shmflg); 이다.
int shmid : 공유 메모리를 생성할 때 만들어진 공유 메모리의 ID, xshmaddr : 공유 메모리가 할당된 주소, int shmflg : 공유 메모리 사용옵션을 지정한다. SHM_RND 옵션은 공유 메모리 주소를 프로세스에 맞게 따로 할당한다. SHM_RDONLY 옵션은 공유 메모리를 읽기 전용으로 설정한다.
shmdt() 함수는 프로세스에 연결된 공유 메모리 공간의 사용을 끝낸 후 프로세스와 공유 메모리 공간의 연결을 끊는 함수이다.
shmdt() 함수를 사용하기 위해서 <sys/types.h>, <sys/shm.h>의 헤더파일을 선언해야 한다. 원형은 int shmdt(const void xshmaddr); 이다.
xshmaddr : 공유 메모리가 할당된 주소이다.
위의 함수를 바탕으로 공격 코드를 작성해보자.
아래와 같이 공격 코드를 작성해보자. 위의 함수들을 이해했다면 작성하기 쉬울것이다.
1. 공유 메모리를 생성하고 해당 메모리에 값을 쓴다.
2. 프로세스에서 공유 메모리를 사용할 수 있게 연결한다.
3. 공유 메모리 공간에 있는 값을 특정 변수에 복사한다.
4. 프로세스에서 공유 메모리의 연결을 분리한다.
다음과 같이 공유 메모리에 저장된 값이 level11의 패스워드라는 것을 알 수 있다.
'Wargame > FTZ' 카테고리의 다른 글
해커스쿨 FTZ level12 (버퍼 오버 플로우) (0) | 2018.08.01 |
---|---|
해커스쿨 FTZ level11 (포맷 스트링 버그) (0) | 2018.08.01 |
해커스쿨 FTZ level9 (0) | 2017.08.21 |
해커스쿨 FTZ level8 (0) | 2017.08.20 |
해커스쿨 FTZ level7 (0) | 2017.08.19 |