WAR GAME/Nebula

[Exploit-Exercises: Nebula] level01 풀이

jir4vvit 2020. 5. 14. 22:21

환경설정 : iso 파일을 이용하여 서버를 연 후, cygwin을 이용하여 ssh로 서버에 접속함.

* level01

ID: level01

PW: level01

 

level01 문제

아래 프로그램에는 임의의 프로그램을 실행할 수 있는 취약점이 있는데, 찾을 수 있는가?
이 단계를 수행하려면 level01 계정으로 로그인해라. 이 레벨의 파일은 /home/flag01에서 찾을 수 있다.

 

문제를 푸는 방법 : 다음 레벨의 패스워드를 얻는 것이 아니라 flag01의 권한을 획득하여 getflag를 실행시키는 것

 

 


 

일단 코드를 보지않고(?) 문제를 대충 풀어보았다.(?)

확인해보니 flag01은 setUID가 걸린 파일이었다.

이것과, 세미콜론(;) 두개의 명령어를 이어서 쓸 수 있다는 것을 가지고 풀어보려고 했으나 안되었다.

 


 

문제에서 제공해 준 코드를 한번 봐야겠다.

문제에서 제공 해 준 코드

일단 저기 빨간색 네모친 부분을 보겠다.

위에 gid_t 와 uid_t는 각각 getegid()와 geteuid()의 반환값 타입이다.

 

그러면 getegid()geteuid()는 뭘까?

 

get은 보통 getter로 가져올 때 많이 쓰기 때문에 저 함수들은 각각 egid와 euid라는 것을 가져오는 것 같다.

 

그 전에 uid가 뭔지부터 알아봐야겠다.

 

출처는 내 블로그ㅎ

uid는 나 자신을 의미하는 것 같다.

 

그러면 euid란 뭘까? 그 전에 setUID가 뭔지 다시 정리를 해보겠다.

 

setUID는 일시적으로 자신의 ID를 변경하는 것을 말한다.

 

  1. setUID는 파일에 걸리는 것
  2. setUID가 걸린 파일을 실행하면 나의 아이디가 잠깐 변경이 됨
  3. 파일의 실행이 끝나면 다시 원래의 아이디로 돌아옴

여기에서 나의 아이디가 잠깐 변경이 되는 게 Effective UID (flag01) 원래의 아이디는 Real UID (level01) 이다.

 

참고로 euid가 보안 측면에서 위험하다고 말하는 경우가 있다.

이유는 자기가 자기권한(Real UID)만 쓰는 것이 아니라 다른 계정의 권한(Effective UID)를 쓸 수 있기 때문에 보안측면에서 위험하다.

 

그래서 setUID는 적절하게 제한적으로 사용이 되어야 한다.

 

그러면 다시 생각해보자.

 

setUID 프로그램을 실행시키게 되면 두 가지 권한이 공존하게 된다. (euid, ruid)

프로그램의 종류에 따라 euid인지 ruid인지 둘 중 하나가 적용이 되어 프로그램이 실행되게 된다. 일반적으로 euid가 적용이 된다고 한다.

 

문제에서 제공 해 준 코드

결론적으로 getegid()와 geteuid()는 다른 계정의 gid와 uid를 가져오는 것을 알 수 있다.

 

이제 아래 네모 친 부분을 살펴보자.

 

보통 set은 무언갈(?) 바굴 때 이름을 붙인다.

그걸 통해 보면 위에는 resgid, 아래는 resuid를 각각 위에서 정의한 gid와 uid로 바꿔주나 보다.

 

여기서 res는 Real uid, Effective uid, Saved set-uid를 뜻한다.

참고로 Saved set-uid는 이전의 euid를 뜻한다. 실행이 그만두면 원래 있던 euid값을 복사해온다고 한다.

 

결론적으로 저 함수들을 보면, Ruid, Euid, Saved setuid를 전부 Euid로 변경해주고 있는 것을 알 수 있다. (setresgid()도 마찬가지)

왜... 이런 걸 하는 걸77ㅏ...?

 

이유는 시스템이 무조건 euid(flag01)로 인지하도록 하기 위해서 인 것 같다.

아까 위해서 setuid가 걸린 파일은 ruid와  euid 중 한가지 권한으로 실행된다고 했다. 보통은 euid지만 간혹가다가 ruid인 경우가 있을 수 있다. 이를 방지하기 위해 resuid를 euid로 바꾸어 한가지 권한으로만 예측된 결과를 얻기위해서 저 함수를 썼다고 예측할 수 있다.

 

 

문제에서 제공 해 준 코드

이제 마지막 줄을 해석해보자...! 거의 다 왔다 화이팅!

 

저기 system 안의  " "를 보면 두 부분으로 쪼갤 수 있다.

 

  • /user/bin/env
  • echo and now what?

이렇게 두 부분으로 쪼갤 수 있다.

 

무슨 차이인지 아시겠나? 위에는 절대경로이고 아래는 상대경로로 명령어가 표현되어 있다.

절대경로로 명령어가 입력이 되면 환경변수인 PATH에 영향을 받지않지만, 상대경로로 입력이 되면 PATH에 영향을 받게 된다. 죽, PATH의 우선위가 제일 높은 곳의 echo를 기준으로 명령어가 실행이 되는 거다.

 

이는 echo가 setUID와 결합되는 경우, 타 계정의 파일에 접근할 가능성이 있다는 것을 보여준다.

 

이것을 이용하여 문제를 풀어보도록 하겠다.

 


 

정리

  1. flag01 파일이 flag01 계정으로 setUID가 걸려있으니까, 파일을 실행하면 저 flag01권한으로 echo도 실행이 되겠구나?
  2. echo라는 쉘 스크립트를 /home/level01에 만들어서, echo의 절대경로의 우선순위를 /home/level01이 제일 높게 만들어 주자.
  3. echo 쉘 스크립트 안에 쓰여져야할 것은 권한을 계속 유지하는 /bin/bash
  4. 결론적으로 flag01의 권한을 쭈욱 획득하게 되니까 getflag를 적으면 문제가 풀릴 것 같다.

 


 

진짜 본격적인 문제풀이에 들어가보겠다.

여기에 echo를 만들어 볼 것이다.

echo 파일의 안은 이렇게 구성이 된다.

 

원래 우리가 아는 메아리 echo 위치와 방금 우리가 작성한 echo의 위치를 파악해 보았다.

이제 환경변수에서 /home/level01의 우선순위를 제일 높게 추가시켜야 한다.

 

이렇게하면 /home/level01의 우선순위가 제일 높아진다. ($PATH는 기존의 PATH를 의미하고 :으로 각 PATH가 구분된다.)

 

 

이렇게 flag01을 실행시키고 계정이 flag01로 바뀐 것을 확인하였다.

계정이 바뀌고 getflag를 입력하니 성공적으로 getflag를 발동시켰다고 뜬다!!!!!!!!!!!!!!!!

 

 

끝!