본문 바로가기
스터디/멘토링

[2020 하반기] 11/07 멘토링 5주차 시스템 해킹

by 맑은청이 2020. 11. 7.
728x90
반응형

5주차 멘토링을 시작합시다~ 광고를 누르면서 시작해볼까요

 

이번 주는 '시스템 해킹' 이고 시간이 남으면 저번보다 어려운 리버싱 문제를 풀어볼까 싶습니다~

 

시스템 해킹을 배우는데 가장 유명한 사이트이면서도 시스템 해킹을 배우는 사람이라면 거의 반드시 걸치는 '해커스쿨' 로 멘토링을 할거랍니다.껄껄

 

VMware 을 설치했으니 아래에서 FTZ 이미지를 다운 받읍시다. 

 

drive.google.com/file/d/1krZs8e6QG_l_mxMI3eCY11F-lgb12HLb/view

 

FTZ.zip

 

drive.google.com

Vmware_Redhat_9_FTZ.zip 압축파일이 나오는데 이를 풀면 'Red Hat Linux.vmx' 파일이 있습니다. 이를 실행합시다.

실행시키고 'I Copied It' 을 눌러주고 OS 부팅이 끝나고 설치 완료될 겁니다.

아이디는 root

패스워드는 hackerschool 

로그인 후

ifconfig 명령어를 통해 서버 아이피를 체크

 

다음은 Putty 를 다운 받고 SSH 로 원격 접속을 해줍시다.

 

www.putty.org/

 

Download PuTTY - a free SSH and telnet client for Windows

Is Bitvise affiliated with PuTTY? Bitvise is not affiliated with PuTTY. We develop our SSH Server for Windows, which is compatible with PuTTY. Many PuTTY users are therefore our users as well. From time to time, they need to find the PuTTY download link. W

www.putty.org

 

자기 서버 IP 주소를 입력해주고 SSH로 포트는 22포트 이용해서 열어줍시다. 설정을 저장합시다. FTZ 로 Save~

 

앞으로 해커스쿨 FTZ 로컬 서벙[ 접속하기 위해서는 먼저 가상머신에서 로컬 서버부터 열어주고 Putty 로 SSH 접속하여 사용하면 됩니당 굿굿

 

 

training 단계가 끝났으면 level1 풀어봅시당/

 

시스템 해킹을 하기 위해서 핵심적인 거는 메모리 구조에 대한 이해입니다. 시간이 나시는 분은 달고나 문서를 읽어보세용. 버퍼오버플로우를 공부할 수 있는 굉장히 좋은 문서이죠.

 

%EC%99%80%EC%9A%B0%ED%95%B4%EC%BB%A4%20BOF%20%EA%B8%B0%EC%B4%88%EB%AC%B8%EC%84%9C.pdf

 

 

나온지 몇십년이나 됐지만 아직도 유명한 버퍼 오버 플로우나 저번 주에 한 리버싱 같은 시스템 해킹 기법을 이해하기 위해서는 메모리 레이아웃을 반드시, 바아안드시 이해해야합니다.

 

그럼 메모리가 어떻게 구성되었는지 확인해봅시다.

 

code segment

:기계어 코드로 컴파일러가 만들어낸 코드, 즉 instruction 가 들어있다. 주소도 들어있는데 메모리 상 컴파일 과정에서 어디에 저장될 지 알 수 없기 때문에 logical address 를 사용한다. 즉 실제 주소 physical address 와 매핑되어 있고 이는 자신의 시작 위치(offset)을 찾을 수 있다. 

physical address = logical addres + offset

 

data segment 

:프로그램이 실행시에 사용되는 데이터, 여기선 전역 변수가 들어간다.

 

stack segment

: 현재 수행되고 있는 프로그램이 저장하는 데이터 영역으로 우리가 사용할 버퍼가 이 곳에 저장된다. '지역 변수' 가 자리 잡는 곳이다.

 

스택은 정말 중요한 자료구조 개념인데 컴퓨터는 스택 구조로 되어 있습니다. 처음 생성될 때 필요한 크기 만큼 만들어주고 프로세스의 명령에 의해 데이터를 저장해 나가는 과정을 거치게 되는데 이를 stack pointer(SP)라고 하는 레지스터가 스택의 맨 꼭대기를 가리키고 있다. PUSH/POP 을 통해 스택의 크기가 조절 되게 된다. 

 

메모리 구조를 파악하기 위해 다음 코드로 생각을 해봅시다.

 

다음 코드들이 어디로 배치될지 생각해봅시다.

 

 

스택과 힙은 반대로 간다는 거 기억해둘 가치가 있습니다. 이는 커널을 보호하기 위함이기도 하져!

function(int a,int b,int c) 에서 전달하는 인자의 순서는 어떻게 될까요?

 

a,b,c 라고 생각할 수 있지만 stack 형태니깐 c,b,a 순서져!

 

백도어의 개념을 설명해볼까여?

 

 

문제를 한번 풀어봅시다. 

 

 

level1/level1으로 로그인해줍니다. 

 

서버의 파일 구조를 파악해줍니다. 

 

ls -l 을 하면 알겠져?

hint 를 확인해봅시다. cat hint 면 되겠져?

힌트를 보니 level2 와 관계있는 백도어를 찾아서 level2 권한을 얻으면 된다는 걸 알 수 있겠죠. 

여기서 level2 권한의 백도어란 level2 계정의 소유이고 다른 계정으로 그룹 권한이 부여돼 있는 SetUID와 SetGID가 설정되어 있어야한다는 의미입니다. 

 

 

그럼 공격할 대상 파일을 찾기 위해 find 명령을 사용해봅시다.

여기서 -peem +6000 옵션은 level2 권한과 level1 의 그룹 권한 중 하나라고 SUID, SGID 로 설정된 파일을 찾는 옵션이고 2> /dev/null은 에러 발생한 결과는 버리겠다는 의미합니다. 셸에서 숫자 1은 표준출력(STDOUT)이고 2는 표준에러(STDERR)를 의미하져. 즉 쓰레기 통이져 

/bin/ExecuteMe 만 나왔네여. 대상 파일을 찾았으니 리버싱을 해야해요.

쫄지 맙시다.

 

마음 편하게 gdb /bin/ExecuteMe 

disas main

 

 

gdb를 이용해봅시다. 

 

코드는 길지만 흐름을 설명해봅시다.

 

1.스택을 구성

2. system() 함수로 명령어 실행

3. chdir()함수로 디렉토리로 이동 

 

4. printf()를 통해 문자열 출력

5.fgets()함수를 통해 사용자 입력 받기

6.strstr()함수를 이용해 위에서 받은 입력이 문자열 금지 명령어인 my-pass,chmod 와 비교

chmod 는 권한 변경을 막기 위한 거고 my-pass 차단을 백도어 셸 실행된 level2 권한에서 쉽게 패스워드를 못 보게 한 것.

7. 해당 결과에 따라 금지어가 아닌 경우 실행 루틴으로 넘어감

 

8.setreuid(3002,3002) 함수를 통해 실행되는 파일의 User ID 권한을 level2계정으로 설정

 

9.system() 함수를 통해 입력 받은 문자열을 리눅스의 명령어로 실행

 

 

 

 

 

 

 

 

 

 

 

 

 


system("/usr/bin/clear") 를 실행해서 서버에서 clear 명령어를 실행해 화면을 지웁니다.

 chdir("/home/leverl2") 라는 코드가 실행되면서 서버에서 "/home/level2" 디렉토리로 이동하는 걸 알 수 있져

 

계속 스택에 push 되면서 쌓이는 문자열들을 확인해봅시다

이게 printf() 되고여

즉 레벨 2의 권한으로 원하는 명령어를 한가지 실행시켜준다는데 그게 my-pass 와 chmod 는 안된다는 거죠?

 

참고로 필자는 연구실에서 피벗기능을 사용해서 편하게 어셈블리 코드를 보고 있으나 다른 분들은 좀 힘들겠네여.

 

 

그럼 이때까지 분석한 게 맞는지 실행을 시켜봅시다.

/bin/ExecuteMe 로 실행시켰는데 분석 내용과 동일하져?

그럼 다시 분석해나가봅시다.

 

fgets 바로 위 push 값을 확인해보면 다음과 같져

 

보면 fgets(배열 주소, 0x1e == 29 , STDIN) 으로 거꾸로 들어오는 걸 알 수 있져?

브레이크를 걸어놓고 실행해서 입력값이 정확하게 들어가는 걸 확인해봅시다. 

슬프게도 오류가 뜨네요.

 

SetUID 가 걸린건 이렇게 뜬다네요.

해결법은 위치 옮겨주기

근데 이것도 level2 권한으로 실행은 안되네

 

그냥 계속 분석해 봅시다

strstr 이랑 printf 에 넣어지는 거 분석~

chmod 를 못치게 하네요. 권한을 수정할 수 있으니깐요

같으면 안되고 아니면 실행하겠져? 

 

여기서 0xbba == 3002 입니다. level2의 그룹 ID 져~?

즉 my-pass도 chmod 도 아니면 그룹 ID 권한으로 명령어를 실행하는 부분이 아래 부분이져?

총 코드는 다음과 같아지겠네요.

 

 

 


 

이 문제의 의도는 공격자가 리눅스 운영체제의 권한 체계를 이해하고 있는가를 묻고 있는 겁니다. 

 

유닉스 계열의 운영체제는 다른계정에서 읽기(R) 쓰기(W) 실행(X) 권한을 줄 수 있는데 이렇게 권한을 줄 때 SUID,SGID를 사용하면 다른 계정에서 만든 파일을 내 계정에서 읽거나,쓰거나, 실행할때 다른 계정의 권한을 잠시 얻을 수 있습니다. 

 

따라서 문제의 의도는 이러한 개념을 알고 있는지 역서 다른 계저으이 권한을 얻은 일시적인 순간에 어떻게 my-pass 명령어를 사용 차단 함으로 어떻게 얻을지 고민하게 하네요.

 

일시적으로 다른 계정의 권한을 얻은 상황에서 이 권한을 유지할 수 있는 대표적인 방법 가운데 가장 간단한 건 '배시셸'을 실행하는 겁니다. 그러면 프롬프트가 생기면서 일시적으로 얻었던 level2의 권한이 유지됩니다. 조금 더 설명하면 일시적으로 명령어를 한 번만 실행시킬 수 있는 상태에서 level2소유의 정상적인 셸에 쭉 머무릴 수 있다는 겁니다.

바로 권한이 바뀌는 걸 볼 수 있는데 우리는 셸을 따내야한다. 

 

공격은 다음과 같은 순서로 진행됩니다.

1. 로그인 후 계정의 파일 구조 확인

2. 문제와 관련된 힌트 

3. 취약점 있는 파일 검색

4. 공격 대상 파일을 실행해 파일의 동작 방식 확인

5. "sh"나 "bash"같은 셸 실행 명령어를 통해 level2 권한의 셸 획득

6. level2의 패스워드 확인

7. 5번 방식 같이 셸 명령어가 아닌 vi 편집기를 이용해 우회법 추가 확인 

 

자 그럼 체력로 합시다. 지금 사실 4번 까지 했어염

 

단 한번의 명령어로 셸을 실행시킬 수 있는 'sh','bash'

\

여기서 my-pass 를 치면 패스워드가 나온다. 

 

 

지 SUID와 SGID는 유닉스 시스템에서 파일에 다른 계정과 그룹의 권한을 일시적으로 빌려주는 개념이다. 일반적인 RWX와는 다른 독특한 개념이라고 할 수 있다. 즉 SUID가 설정된 파일은 해당 파일을 실행하는 동안은 일시적으로 파일 소유자의 계정으로 잠시 바뀌게 된다는 것. 

 

 

728x90
반응형