gunnew의 잡설

pwnable.kr 10. shellshock 본문

System Security

pwnable.kr 10. shellshock

higunnew 2020. 2. 14. 17:03
반응형

 이번 게임도 개념을 안다면 정말 쉬운 문제였지만, 나는 몰랐기에 여기저기 많이 뒤져보았다. 이번 문제를 이해하기 위해서는 Bash(그냥 우리가 쓰는 쉘임)의 환경변수 설정에 대해 알아야 한다.


1. Bash 환경 변수 설정

 

Bash에서 환경 변수를 세팅해보자. foo=3을 대입하고 export foo를 해주면 env에 foo=3이 등록될 것이다.

 


 

그리고 환경 변수 대신에 환경 함수(?)를 설정할 수도 있다. foo()라는 함수를 hi를 출력하도록 해보자. 다음과 같이 foo() { echo hi; } 와 export -f foo를 하면, foo=3과 foo() { echo hi; }가 동시에 등록될 것이다.

 


 

근데 옛날 bash에서는 foo 환경 변수를 설정하는 것처럼 환경 함수(?)를 설정할 수도 있다. 다음 예시를 살펴보자. foo='() { echo new_func; }'는 분명 환경 변수로서 값이 () { echo new_func; }가 들어갈 것이라고 생각된다. 실제로도 env를 통해 확인하면 그렇다.

 원래 이렇게 foo라는 함수가 정의되지 않고 변수로 정의되기 때문에 foo를 치면 오류가 뜨는 것이 정상이다. 그러나 shellshock에 대해 검색을 해보니 옛날(이라고 하기엔 불과 5년 전) bash에서 발견되는 문제점으로, 환경 함수(?)를 환경 변수로 설정하는 것처럼 설정할 수 있다. 아하 그래서 여기서는 bash 실행 파일을 따로 줬구나! 

 

심심하다면 밑에 문서들을 읽어보자.

https://en.wikipedia.org/wiki/Shellshock_(software_bug)

 

Shellshock (software bug) - Wikipedia

Shellshock, also known as Bashdoor,[1] is a family of security bugs[2] in the Unix Bash shell, the first of which was disclosed on 24 September 2014. Shellshock could enable an attacker to cause Bash to execute arbitrary commands and gain unauthorized acce

en.wikipedia.org

그리고 꺼무위키도 한번 볼까..?

https://namu.wiki/w/%EC%85%B8%EC%87%BC%ED%81%AC

 

셸쇼크 - 나무위키

본격적으로 설명하기에 앞서 Bash의 환경변수에 대해 간략하게 알아보자. $ hi="안녕!" $ echo $hi 안녕!hi라는 변수를 생성, echo 함수를 통해 출력하는 구문이다. $hi를 입력했을 때 Bash shell은 c의 매크로처럼 "안녕!"이라고 변환해준다. $ hi="안녕!" $ export hi $ printenv | grep hi hi="안녕!"이번엔 변수를 선언하고 export를 통해 환경변수에 등록해보자. printenv로 환경변수 목

namu.wiki

 아무튼! 지금까지 알 수 있던 것은 환경 변수로서 사실은 환경 함수(?)를 세팅할 수 있었는데 환경 변수를 설정하는 것처럼 환경 함수(?)를 설정해도 인식이 되지 않았다. 위에서 foo='() ~'이렇게 입력했지만 여전히 환경 변수로만 나왔지 함수로서는 동작하지 않았다. 그러나 위에 있는 두 위키를 읽어보면 옛날 bash 환경에서는 환경 변수를 설정하는 것처럼 함수로 설정할 수 있었다. 그 오래된 bash에서 함수를 실행해 보자.

 

띠용?

 지금 실행되는 쉘이 아니라 여기에서 실행 파일로 준 bash를 실행시켜 subshell로 foo를 실행해 보았더니 함수로 인식이 됐다! 이 엄청나고 탐스러운 보안 문제는 더 확장될 수 있다.


2. 권한 문제 (setresuid(), setresgid(), getegid(), ...)

음... 코드를 보니 id가 뭐 그리 많이 나오는지... setresuid, setresgid, getegid 다 뭔지 모르겠다. 문제에 필요한 개념을 간단히 살펴보자.

Read ID : 실제로 접속한 사람이 누구인지 나타낸다. 프로세스를 실행시킨 User의 ID이다.

Effective ID : 접속한 사람이 누구인지와는 다르게 실제로 프로세스를 실행하면서 파일 등에 access 할 때 갖게 되는 권한을 말한다. 

예를 들어,

$ ls -al 
... 
-rwxr-xr-x. 1 owner group1 30723 oct 11 13:40 myjob 
-rw-r--r--. 1 owner group1 30723 oct 11 13:40 myjob.txt

 위의 myjob은 user, group, other에게 모두 실행 권한이 존재한다. 따라서 other도 myjob을 실행할 수 있다. 그러나 myjob.txt를 건들고 무언가를 덮어 씌우려고 한다면 문제가 생길 것이다. myjob.txt는 other에게는 읽기 권한만 주었기 때문이다.

 그럼 이걸 어떻게 처리해야 하는가?

 

1. myjob.txt의 권한을 변경하는 방법이 떠오른다. 그러나 이것은 좀 무식하다. myjob의 권한을 -rw-rw-rw-로 부여하게 되면 아무나 들어와서 이 파일을 형식에 맞지 않게 맘대로 바꿔 재껴 버릴 것이다. 그러면 문제가 생길 것이 분명하다.

 

2. 프로그램에 effective user 권한을 부여하는 방법이 있다.

chmod u+s myjob 명령어를 실행하여 myjob 실행 파일에 effective user 권한을 부여한다면 

다음과 같이 바뀐다.

 

$ ls -l 
... 
-rwsr-xr-x. 1 user1 group1 30723 oct 11 13:40 myjob
-rw-r--r--. 1 user1 group1 30723 oct 11 13:40 myjob.txt

 -rwsr-xr-x 이렇게 될 것이다. 이렇게 되면 other 로 ./myjob을 실행하면 Real ID는 other의 ID가 되지만 Effective ID는 user1이 되어 myjob 프로세스는 myjob.txt에 쓰기 권한이 생긴다. 이렇게 되면 other들은 이 프로그램을 제외한 다른 방법으로는 myjob.txt를 수정할 수 없다. 이것을 사용하는 대표적은 예시로 비밀번호 변경이 있다. 만약 비밀번호를 담은 테이블의 권한을 맘대로 수정할 수 있게 한다면 그 시스템은 완전히 망가질 것이다. 따라서 특정 프로그램을 실행하고 해당 프로세스를 통해서만 비밀번호를 변경할 수 있게 만드는 것이 Effective ID 권한 설정이다.

 

 다시 문제로 돌아가 보자.

shellshock@pwnable:~$ ls -l
total 960
-r-xr-xr-x 1 root shellshock     959120 Oct 12  2014 bash
-r--r----- 1 root shellshock_pwn     47 Oct 12  2014 flag
-r-xr-sr-x 1 root shellshock_pwn   8547 Oct 12  2014 shellshock
-r--r--r-- 1 root root              188 Oct 12  2014 shellshock.c

잘 보면 shellshock 실행 파일에 그룹 실행 권한에 -r-xr-sr-x가 보일 것이다. 아 참 그리고 현재 id들을 확인해보자. 현재는 id는 shellshock이다. 그런데 그룹 실행 권한에 s가 있다는 것은 해당 프로세스를 other인 shellshock이 실행하더라도 effective group id가 shellshock_pwn이 되고, 해당 프로세스 내에서 other가 접근하지 못했던 것들에 접근할 수 있는 권한을 부여한다. 예를 들면 flag와 같은 파일들 말이다.

 


이것들을 종합하여 payload를 작성해보자.

 

 원래 당신이 아는 대로 함수의 정의문이 { }로 구분되며 이 중괄호 block이 끝나면 뒤에 것은 실행되지 않는다. 다음 예시를 살펴보자. 이것은 현재 실행되는 bash (실행 파일로 존재하는 구버전 bash 아님)를 이용했을 때이다.

 

foo에다가 아무런 것도 써넣지 않고 함수 정의문이 끝나고 나서 echo maybe not printed라는 명령어를 입력하였고 이 환경 함수(?) 정의가 끝나고 나면 bash를 통해 must be printed를 출력하게 하였다. 예상대로 must be printed만 출력된다. 그러나!

띠용? 옛날 bash로 실행하니까는 foo 환경 함수(?) 정의가 끝난 뒤에 있는 명령도 실행된다. 이러면 안 되는데... 이게 바로 shellshock 취약점이다. 

 

그럼 이걸 이용하면 

shellshock를 실행하고 난 다음 "/home/shellshock/bash -c 'echo shock_me'"를 실행할 텐데 이때 환경 변수 설정의 취약점을 통해 echo를 재정의 해주면 될 것이다.

 

 

반응형

'System Security' 카테고리의 다른 글

pwnable.kr 12. blackjack  (0) 2020.02.17
pwnable.kr 11. coin1  (0) 2020.02.16
pwnable.kr 9. mistake (Operator priority)  (0) 2020.02.12
pwnable.kr 8. leg (ARM Assembly)  (0) 2020.02.12
pwnable.kr 7. input (Various I/O in Linux)  (0) 2020.02.06
Comments