write-up/pwnable

[ftz] level3: can you fly?

여니두 2019. 7. 28.

03_system() 함수의 위험성

 

autodig 파일을 실행시켜 권한을 얻어 my-pass로 password를 얻으면 될 것 같다.

 

√ system() 함수?

: 시스템에 명령을 실행할 때 사용하는 함수

- 대부분의 프로그래밍 언어에 있음

→ 프로그램 개발 시 반드시 필요한 함수라는 것.

 

√ dig, nslookup

- nslookup: 도메인 서버의 IP 주소를 확인하는 프로그램

: 고급 옵션까지 알고 있다면 DNS 서버 설정이 취약한 서버의 DNS 설정을 뽑아올 수도 있음

- dig: nslookup과 동일한 기능. 기본적으로 유닉스 계열에 탑재돼 있음.

 

√ dig 사용법

- dig: Domain Information Groper = DNS 진단용 유틸리티

- nslookup보다 더 상세정보가 포함되어 있다.

dig @쿼리할 DNS 서버의 IP

 

autodig의 소스코드를 자세히 살펴보자.

 

// 인자의 개수가 1개가 아니면 종료 >> 인자 1개여야 함.

 

* main 함수 인자 값

- argc: 입력 받는 인자의 개수 (기본 1)

- argv[]: 실제로 입력 받은 인자를 배열로 저장.

0번째는 실행 경로가 들어가므로 1번째부터 실제 인자 값이 들어간다.

 

>> system(dig @argv[1] version.bind chaos txt)

 

* 함수 정리

1. strcpy(DST, SRC): 문자열 SRC가 NULL을 만날 때 까지, DST에 복사

2. strcat(DST, SRC): 문자열 DST 뒤에 SRC의 내용을 결합

3.system(): 외부 명령이나 외부 실행파일을 실행 가능

 

>> autodig 명령: 입력받은 문자열에 해당하는 DNS 서버에서 운영중인 BIND 프로그램의 버전을 확인하는 명령을 실행

: 해당 서버에서 취약한 버전을 운영 중인지 확인할 수 있는 유용한 명령

 

 

√ 공격 대상 파일 찾기 (autodig)

우선 level4 권한의 setuid가 걸린 파일을 찾아보니 autodig 파일이 나온다.

/bin/autodig 파일을 실행시켜 권한을 얻어 my-pass로 pwd를 얻어보자.

 

* 공격 대상 파일 기능 분석

autodig 파일 실행한 것과, 실제 dig 명령을 실행시켜 본 결과 같은 결과가 출력된 것을 볼 수 있다.

 

√ gdb로 소스코드 분석

위 노란색으로 칠한 부분은 인자값(argv[1])을 입력하는 부분이다.

여기에 bp를 걸어준 후, 인자값을 주어 실행시켜 보자.

이제 소스코드 처음부터 쭉 분석할 것이다.

- procedure prelude 과정

- <main+16> EBP+8 위치의 값이 0x02와 같은지 비교

- <main+20> 같다면(2가 맞으면) <main+69>로 점프

위에서 bp를 걸고 인자값을 주어 r로 실행시켰으니, $ebp+8의 값을 확인해 보면 2가 제대로 들어갔음을 확인할 수 있다.

우선 한번 입력 인자수가 1개만 되게 autodig만 입력해보았다.

if문이 실행됨을 확인할 수 있다.

>> strcpy(cmd, "dig @")

>> strcat(cmd, "168.126.63.1")

>> strcat(cmd, " version.bind chaos txt")

 

>> setreuid(3004, 3004)

: /bin/autodig를 실행하는 동안 level4가 되게 만듦.

>> system("dig @168.126.63.1 version.bind chaos txt")

: 168.126.63.1에 대한 BIND 프로그램의 버전을 조회하게 된다.

 

√ 공격

인자를 2개 전달할 경우, 다음과 같은 error 메시지가 뜬다.

hint에 나와있던 more hints를 보자.

- 동시에 여러 명령어는 세미콜론(;)을 이용하면 될 것이다.

- 문자열 형태는 큰따옴표로 감싸면 된다!

위 hint들을 이용해서 "168.126.63.1 www.naver.com" 이렇게 전달하면, 하나의 인자로 처리할 수 있을 것이다.

 

>> 우리는 argv[1]에 통째로 하나의 인자 값을 주어야 하기 때문에 ; 세미콜론과 "" 큰따옴표를 이용해서 문자열 처리를 해주자.

 

* ; 세미콜론

: 셸에서 명령어를 한 줄에 연속해서 적을 때 이용할 수 있음

: system() 함수에서도 동일 적용

 

1)

Level4 Password = "suck my brain"

 

"아무 IP 문자열 ;my-pass;"

 

2)

이렇게 ; 뒤에 sh 명령어를 넣어 셸을 딴 후 my-pass를 확인하는 방법도 있다.

이렇게 되면 autodig 실행되면서 level4 권한을 얻은 후 그 권한으로 셸을 실행시킬 수 있다.

 

3) level4의 백도어 셸 만들기

- 백도어를 만들어 줄 소스코드를 /tmp/superBackoor.c에 생성.

- 컴파일하면 level4 계정의 사용자 ID와 level3 계정의 그룹 ID를 가진 실행파일이 만들어짐.

 

아직 이 파일은 모든 권한이 level3에 있기 때문에, SUID를 설정해 준다.

 

'write-up > pwnable' 카테고리의 다른 글

[ftz] level5: what is your name?  (0) 2019.08.12
[ftz] level4: suck my brain  (0) 2019.07.28
[ftz] level2: hacker or cracker  (0) 2019.07.25
[ftz] level1: find local shell backdoor  (0) 2019.07.25
메모리 레이아웃 기초  (0) 2019.07.24

댓글